shared_ptr


C++11 shared_ptr(智能指针)详解
参考:http://c.biancheng.net/view/430.html
以下是你内容:


要确保用 new 动态分配的内存空间在程序的各条执行路径都能被释放是一件麻烦的事情。C++ 11 模板库的 头文件中定义的智能指针,即 shared _ptr 模板,就是用来部分解决这个问题的。

只要将 new 运算符返回的指针 p 交给一个 shared_ptr 对象“托管”,就不必担心在哪里写delete p语句——实际上根本不需要编写这条语句,托管 p 的 shared_ptr 对象在消亡时会自动执行delete p。而且,该 shared_ptr 对象能像指针 p —样使用,即假设托管 p 的 shared_ptr 对象叫作 ptr,那么 *ptr 就是 p 指向的对象。

通过 shared_ptr 的构造函数,可以让 shared_ptr 对象托管一个 new 运算符返回的指针,写法如下:
shared_ptr ptr(new T); // T 可以是 int、char、类等各种类型

此后,ptr 就可以像 T* 类型的指针一样使用,即 *ptr 就是用 new 动态分配的那个对象。

多个 shared_ptr 对象可以共同托管一个指针 p,当所有曾经托管 p 的 shared_ptr 对象都解除了对其的托管时,就会执行delete p。

例如下面的程序:

#include 
  #include 
  using namespace std;
  class A
  {
  public:
      int i;
      A(int n):i(n) { };
      ~A() { cout << i << " " << "destructed" << endl; }
  };
  int main()
  {
      shared_ptr sp1(new A(2)); //A(2)由sp1托管,
      shared_ptr sp2(sp1);       //A(2)同时交由sp2托管
      shared_ptr sp3;
      sp3 = sp2;   //A(2)同时交由sp3托管
      cout << sp1->i << "," << sp2->i <<"," << sp3->i << endl;
      A * p = sp3.get();      // get返回托管的指针,p 指向 A(2)
      cout << p->i << endl;  //输出 2
      sp1.reset(new A(3));    // reset导致托管新的指针, 此时sp1托管A(3)
      sp2.reset(new A(4));    // sp2托管A(4)
      cout << sp1->i << endl; //输出 3
      sp3.reset(new A(5));    // sp3托管A(5),A(2)无人托管,被delete
      cout << "end" << endl;
      return 0;
  }

程序的输出结果如下:

  2,2,2
  2
  3
  2 destructed
  end
  5 destructed
  4 destructed
  3 destructed

可以用第 14 行及第 16 行的形式让多个 sharecLptr 对象托管同一个指针。这多个 shared_ptr 对象会共享一个对共同托管的指针的“托管计数”。有 n 个 shared_ptr 对象托管同一个指针 p,则 p 的托管计数就是 n。当一个指针的托管计数减为 0 时,该指针会被释放。shared_ptr 对象消亡或托管了新的指针,都会导致其原托管指针的托管计数减 1。

第 20、21 行,shared_ptr 的 reset 成员函数可以使得对象解除对原托管指针的托管(如果有的话),并托管新的指针。原指针的托管计数会减 1。

输出的第 4 行说明,用 new 创建的动态对象 A(2) 被释放了。程序中没有写 delete 语句,而 A(2) 被释放,是因为程序的第 23 行执行后,已经没有 shared_ptr 对象托管 A(2),于是 A(2) 的托管计数变为 0。最后一个解除对 A(2) 托管的 shared_ptr 对象会释放 A(2)。

main 函数结束时,sp1、sp2、sp3 对象消亡,各自将其托管的指针的托管计数减为 0,并且释放其托管的指针,于是会有以下输出:

  5 destructed
  4 destructed
  3 destructed

只有指向动态分配的对象的指针才能交给 shared_ptr 对象托管。将指向普通局部变量、全局变量的指针交给 shared_ptr 托管,编译时不会有问题,但程序运行时会出错,因为不能析构一个并没有指向动态分配的内存空间的指针。

注意,不能用下面的方式使得两个 shared_ptr 对象托管同一个指针:
A* p = new A(10);
shared_ptr https://blog.csdn.net/u013360881/article/details/71798950
以下是内容:


程序使用动态内存出于以下三种原因之一
1、程序不知道自己需要多少对象;
2、程序不知道所需对象的准确类型;

3、程序需要在多个对象间共享数据

shared_ptr的用法

可以指向特定类型的对象,用于自动释放所指的对象
eg: shared_ptr PointCloudDlgPointer;//指向类型为CDlgPointCloud的对象PointCloudDlgPointer;

当然还有一个最安全的分配和使用动态内存的方法就是调用一个名为make_shared的标准库函数;

make_shared的用法

make_shared 在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr,与智能指针一样,make_shared也定义在头文件memory中;

当要用make_shared时,必须指定想要创建的对象类型,定义方式与模板类相同,在函数名之后跟一个尖括号,在其中给出类型;

如make_shared p3 = make_shared(42);

一般采用auto定义一个对象来保存make_shared的结果,如auto p1 =make_shared(42);

相关