码迷,mamicode.com
首页 > 其他好文 > 详细

关于智能指针的研究

时间:2020-05-19 12:55:53      阅读:66      评论:0      收藏:0      [点我收藏+]

标签:比较   class   set   方便   如何   就会   rtu   运算符重载   用法   

最近面试的时候面试官问了我一个问题。unique_ptr和shared_ptr到底有什么区别?我一时语塞。回来之后我痛定思痛,决定好好的研究一下智能指针的问题。现在已经研究的差不多了,决定好好的总结一下。

  一、智能指针的用途

  二、智能指针的特性

  三、智能指针的种类与用途

    3.1 最原始的智能指针auto_ptr

    3.2 独一无二的智能指针unique_ptr

    3.3 可以共享的指针shared_ptr

    3.4 智能指针的用途

      3.4.1 智能指针的用途

      3.4.2 unique_ptr和shared_ptr的用途

 

  四、总结

  一、智能指针的用途

  首先我们先设置一种场景,假如我们当前有一个类,类中存放着一个指针用来保存字符串,那么我们应该怎么写呢?

  class CopyConstructor
  {
  public:
      char *p;
  public:
      CopyConstructor(char *str);
      virtual ~CopyConstructor();
      CopyConstructor(CopyConstructor &m_copCon);
      CopyConstructor operator = (const CopyConstructor &m_copCon);
 
      void print();
  };
  好的,那么我们再构造函数中如果想要初始化字符串可以这样写。  
  CopyConstructor::CopyConstructor(char *str)
  {
    cout<<"CopyConstructor::CopyConstructor"<<endl;
    p = new char[strlen(str) + 1];
    strncpy(p, str, strlen(str) + 1);
  }
  
  如果我们现在提出一个需求,就是要让两个对象之间可赋值,就像这样:
  CopyConstructor copConFirst(str);
       CopyConstructor copConSecond(str2);
        copConSecond = copConFirst;
  但是如果这样写的话就会面临一个问题,就是析构函数怎么写?换句话说再析构函数中是否使用delete函数回收之前new出来的空间。那么我们分析一下这个问题
  假如我们不写delete函数,那么当然程序就会导致内存泄漏了,这个恐怕是不成的。
  假如我们写delete函数,那么会导致一个什么结果呢?它只拷贝了指针,但是实际delete掉的是同一个内存空间,会直接导致段错误的。
  好的,为了解决这个问题,我们有三种方法可以解决:
  (1)写一个运算符重载函数,重载=,关于这个的写法请大家参考我的博客《关于拷贝构造函数和运算符重载的问题》。
  (2)使用智能指针。
 
  二、智能指针的特性
   那么为什么智能指针能解决上述问题呢?因为他有两个特性。第一个特性就是自动进行delete,换句话说就算你不写delete那么它也能再最后回收那块空间,绝对不会说内存泄漏这种情况发生。第二个特性就是智能指针是一个指针跟一个空间相对应。(我们先不讨论shared_ptr)。这样就不会导致delete两次了。
  三、智能指针的种类和用途
   3.1 最原始的智能指针auto_ptr
    auto_ptr是最原始的智能指针。他有以下几个特性:1、只要是c++的版本,都能使用auto_ptr,不像后面两种必须使用c++11的版本才行。2、auto_ptr再相互赋值时,会先把原来的指针移成空,然后再把新来的指针指向原来的指针指向的空间。3、auto_ptr只能支持delete,不支持delete []。当然了,它的特性来说的话还是都支持的。
  3.2 独一无二的智能指针unique_ptr
    正因为有上述第二,第三两个问题,因此c++11才出了unique_ptr,它的特性如下:1、unique_ptr是只有c++11版本才能使用的。因此再编译或者再编写makefile的时候要注意以下。2、unique_ptr再相互赋值的时候不能使用=(即copConSecond = copConFirst这样写不可以的)。必须要有恰当的函数。3、unique_ptr可以支持delete []。
    这里稍微说以下如何用unique_ptr进行相互赋值,这当中有三种情况,第一种情况是两个指针都是unique_ptr,第二个情况是我要把unique_ptr变成普通指针,第三种情况是我要把普通指针变成unique_ptr。我们举个例子 
  unique_ptr <AutoPtr> autoPtrFirst(new AutoPtr(1));
       unique_ptr <AutoPtr> autoPtrSecond(new AutoPtr(2));
  AutoPtr *p = NULL;
  好,我们针对以上三种情况进行讨论。
  第一种情况:假如我们要把autoPtrSecond指向autoPtrFirst那么我们应该怎么做呢?我们可以这样写。autoPtrSecond = std::move(autoPtrFirst),即把First指针移动走,只留下Second指针。
  第二种情况:如果我要把unique_ptr指针变成普通指针应该怎么做呢?我们可以这样写。p = autoPtrFirst.release(),这样我们就可以把autoPtrFirst移动走,然后让p指向原来的地址空间了。
  第三种情况:如果我们要把普通指针变成unique_ptr指针应该怎么做呢?我们可以这样写。autoPtrFirst.reset(p),这样我们就可以将autoPtrFirst指向p了。
 
  3.3 可以进行共享的指针
  好的,那么我们看完了前两种智能指针我们可能会产生一个问题:为啥不能两个智能指针指向同一块内存空间呢?答案是可以的。我们使用shared_ptr就可以了。
  关于shared_ptr里面的实现方法我们再这里不做过多的研究和探讨。我们只研究shared_ptr里面的特性。它的特性有如下几点:1、shared_ptr是只有c++11版本才能使用的。因此再编译或者再编写makefile的时候要注意一下。2、shared_ptr和前两者最大的不同在于它支持两个指针指向同一块内存。3、shared_ptr支持delete []。
  3.4 智能指针的用法
    3.4.1 智能指针的用途
      智能指针对于动态分配内存来说非常的方便,但是有以下几个缺点:
      1、智能指针相当于是传指针,这样比传对象要麻烦不少。  
      2、智能指针不太容易知道什么时候结束这个对象,因此对我们分析代码不是一个好的选择。
    3.4.2 关于unique_ptr和shared_ptr的用途
      首先说明一下,auto_ptr这个基本上到c++11以后就被弃用了,基本用的还是后两种。前者一般来说有比较好的安全管理机制,后者来说比较方便。所以各有优劣。
  四、总结
    本文主要研究了智能指针的用途,种类,区别等等。
 
 
     
 
 
 
 
 

关于智能指针的研究

标签:比较   class   set   方便   如何   就会   rtu   运算符重载   用法   

原文地址:https://www.cnblogs.com/songyuchen/p/12915293.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!