c++11 智能指针

来源:互联网 发布:长春虹烨网络培训费用 编辑:程序博客网 时间:2024/05/21 02:33

  如果在程序中使用new从堆(自由存储区)分配内存,等到不需要时, 应使用delete将其释放。c++引入了智能指针auto_ptr, 以帮助自动完成这个过程。 c++11摒弃了auto_ptr,并新增了三种智能指针:unique_ptr, shared_ptr, weak_ptr。


一. auto_ptr, unique_ptr , shared_ptr

头文件:  #include <memory>

用法:  auto_ptr<double>  A(new double);

     unique_ptr<int>    B( new int);

     shared_ptr<string> C(new string>;


  

#include <iostream>#include <memory>#include <string>using namespace std;class Report{public:  Report(const string s) : str(s)  {   cout << "Object create!\n";   }  ~Report() { cout << "Object deleted!\n"; }        void comment() const { cout << str << endl; }private:string str;};int main(){{auto_ptr<Report> ps (new Report("using auto_ptr"));ps->comment();}{shared_ptr<Report> ps (new Report("using shared_ptr"));ps->comment();}{unique_ptr<Report> ps (new Report("using unique_ptr"));ps->comment();}return 0;}

运行结果:


所有的只能指针类都有一个explict构造函数,该构造函数可以将指针作为参数, 因此不需要自动将指针转换为智能指针对象。

shared_ptr<double> p;

double* q =  new double;

p = q; //not allowed, implicit conversion

pd = shared_ptr<double> (q);  //ok, explict conversion


智能指针和常规指针类似, 也能执行 解引用操作(*p), 访问结构成员 (p -> m_), 将它赋值给同类型的常规指针。 还可以将智能指针对象赋给另一个同类型的智能指针对象。


智能指针应避免如下操作:

      string str("hehe");

      shared_ptr<string> A(&str);  //NO!

      ptr过期时,程序将把delete运算符用于非堆内存,这是错误的。


二. 

    对于指向在堆分配的内存的指针, 指针间赋值是不能接受的,因为程序将试图删除同一个对象两次。

    要避免这种问题,方法有多种:

    1. 定义赋值运算符,使之执行深复制。 这样两个指针将指向不同对象, 其中一个对象是另一个的副本。 

    2. 建立所有权概念, 对于特定对象, 只有一个智能指针可以拥有他 ,这样只有拥有对象的智能指针的构造函数会删除对象。 然后, 让赋值操作转让所有权 。 这是用于

         auto_ptr 和 unique_ptr的策略, 但unique_ptr的策略更严格。

    3. 创建智能更高的指针,跟踪引用特定对象的智能指针数。 这称为引用计数。 例如,赋值时, 计数加1, 指针过期时,计数减1, 仅当最后一个指针过期时,才调用delete。这是shared_ptr 采用的策略。


     auto_ptr<string> p1(new string("auto");

     auto_ptr<string> p2;

      p2 = p1;   //OK

     p2接管p1所有权后,p1的所有权将被剥夺。 这样可以防止p1 和 p2的析构函数试图删除同一个对象 。 但如果随后试图使用p1, 这将是件坏事, 因为p1不在指向有效的数据。


     但是如果把上面的auto_ptr换成unique_ptr,编译器会认为 p2 = p1;这句是非法的,这样避免了p1不在指向有效数据的问题, 因为unique_ptr比auto_ptr更安全。

     


weak_ptr是为配合shared_ptr而引入的一种智能指针来协助shared_ptr工作,它可以从一个shared_ptr或另一个weak_ptr对象构造,它的构造和析构不会引起引用记数的增加或减少。没有重载*和->但可以使用lock获得一个可用的shared_ptr对象
weak_ptr的一个重要用途是通过lock获得this指针的shared_ptr,使对象自己能够生产shared_ptr来管理自己,但助手类enable_shared_from_this的shared_from_this会返回this的shared_ptr,只需要让想被shared_ptr管理的类从它继承即可。


0 0
原创粉丝点击