智能指针小记



  • 智能指针模板类

    • 智能指针是行为类似于指针的类对象,但这种对象还有其他功能

    • 使用智能指针:这3个智能指针模板(auto_ptr, unique_ptr, shared_ptr)都定义了类似指针的对象,可以将new获得(直接或间接)的地址赋给这种对象。当智能指针过期时,其析构函数将使用delete来释放内存,因此无需记住稍后释放这些内存

    • 要能使用智能指针对象,必须包含头文件memory,该文件模板定义;例如,模板auto_ptr包含如下构造函数
      template<class X> class auto_ptr{
      public:
      	explicit auto_ptr(X* p = 0) throw();
      	...
      };
      使用如下:
      auto_ptr<double> pd(new double);//new double是new返回的指针,指向新分配的内存块
      //注意到智能指针模板位于名称空间std中;且shared_ptr和unique_ptr是c++11新增的类
      
    • 先说一下全部三种智能指针都应避免的一点:
      string vacation("hansome!");
      shared_ptr<string> pvac(&vacation);
      //pvac过期时,程序将把delete用于非堆内存,这是错的
      
    • 有关智能指针的注意事项:首先,为何摒弃auto_ptr呢?
      auto_ptr<string> ps(new string("I am happy!"));
      auto_ptr<string> vocation;
      vocation = ps;
      //上述代码会导致程序试图删除同一个对象2次
      方法如下:
      (1)定义赋值运算符,使之进行深复制。这样两个指针将指向不同的对象,其中的一个对象是另一个对象的副本
      (2)建立所有权概念,对于特定的对象,只能有一个智能指针可拥有它,这样只有拥有对象的智能指针的构造函数会删除该对象。然后,让赋值操作转让所有权。这就是用于auto_ptr和unique_ptr的策略,但unique_ptr更严格
      (3)创建智能更高的指针,跟踪引用特定对象的智能指针计数。这称为引用计数。例如,赋值时,计数将加1,而指针过期时,指针将减1,仅当最后一个指针过期时,才调用delete。这是shared_ptr采用的策略。
      
    • unique_ptr为何优于auto_ptr:
      auto_ptr<string> p1(new string);
      auto_ptr<string> p2;
      p2 = p1; //在赋值之后p2将接管string对象的所有权,这是好事,防止p1与p2的析构函数试图删除同一个对象;但如果程序后续试图使用p1,则是坏事,因p1不再指向有效的数据
      而上述代码若将声明均改为unique_ptr则编译不会通过,非法操作,避免了p1不再指向有效数据的问题
      //总之,程序试图将一个unique_ptr赋给另一个时,如果原unique_ptr是个临时右值,编译器允许这样做;如果源unique_ptr将存在一段时间,编译器将禁止这样做
      
      相比于auto_ptr,unique_ptr还有一个优点:它有一个可用于数组的变体,即delete[]
      //最后注意:使用new分配内存时,才能使用auto_ptr与shared_ptr,使用new []分配内存时,不能使用它们。不适用new分配内存时,不能使用auto_ptr或shared_ptr;不使用new[]或new分配内存时,不能使用unique_ptr
      
    • 选择智能指针:如果程序要使用多个指向同一对象的指针,应选择shared_ptr;若程序不需要多个指向同一对象的指针,则可使用unique_ptr


 

Copyright © 2018 bbs.dian.org.cn All rights reserved.

与 Dian 的连接断开,我们正在尝试重连,请耐心等待