C++智能指针shared_ptr、unique_ptr和weak_ptr

  • 引言:

在C++中,常使用动态内存,一般情况下常使用new申请,delete释放。

常见的三种情况有:

  1. 程序不知道自己需要使用多少对象
  2. 程序不知道所需对象的准确类型
  3. 程序需要在多个对象间共享数据(申请的动态内存不会随着指针作用域的结束而自动释放)

new分三步执行:1.调用malloc申请动态内存;2.调用传入类型的构造函数;3.判断是否有异常并将其抛出。delete原理相似

例:

int *p1=new int(3);//指针指向一块内存(int 4字节),初值为3
int *p2=new int[10];//指针指向容量为10的一个动态数组。*p ,*(p+1) ,*(p+2),...*(p+9)访问内存

释放动态内存需要手动delete,并且为防止异常最好将指针置为空nullptr。

delete p1;//释放了p1指向的动态内存
p1=nullptr;
delete [] p2;//数组的释放要在指针前面加方括号[]
p2=nullptr;

但!如果程序员粗心或忘了只申请不去手动释放的话,程序中的内存就会越来越多,造成了内存泄漏的问题。那如果有申请后能帮我们自动释放内存的智能一点的指针是不是就很方便了,这也就引入了智能指针的概念。


  • 正文

类似于vector这类的STL容器,智能指针也是模板,所以我们在使用智能指针的时候需要指定类型。

shared_ptr

(一夫多妻制)

允许多个指针指向同一块地址,shared,分享嘛。申请内存后会为该块内存设置一个引用计数,每当指向该内存的指针新多出一个的时候计数+1,指针离开作用域过期后计数-1,当引用计数为0时说明该内存是真的不再需要了,自动释放。

申请动态内存的方式有两种:

shared_ptr p1=make_shared(5);

shared_ptr p2(new int(5));

但是不能shared_ptr p2=new int(5);这是一个关于构造函数显式调用和隐式的概念,有兴趣的同学去了解下。

 

那么分享所有权的操作如下:

shared_ptr p3(p1);

shared_ptr p4;
p4=p1;

unique_ptr

(一夫一妻制)

某个时刻,注意,是某个时刻只能有一个unique_ptr指向一块内存。你离婚再娶没问题,但你没离就想再娶?不好意思,规则不允许(皮一下)。

申请动态内存的方式只有一种:

unique_ptr p1(new int(5));

 

那转让所有权的操作如下:

unique_ptr p2(p1.release());

p1把内存的所有权给了p2,但是p1在此之前需要先release先放手(强扭的瓜虽然解渴但不甜),release会切断unique_ptr和它原来管理的内存之间的联系并且返回指针。

unique_ptr p3(new int(10));
p3.reset(p2.release());

reset()如果有参数,p3指向p2对应的内存;如果无参,将p3置空。


weak_ptr

(确认她有没有丈夫)

与shared_ptr搭配使用。当你拿到了一个shared_ptr的指针时,你无法确定她还有没对应的动态内存,期间也可能会被自动的释放了。weak_ptr应运而生。她绑定到一个shared_ptr时不会改变shared_ptr的引用计数,当计数为0时,即使有weak_ptr指向对象,对象还是会被释放。

绑定:

shared_ptr p1(new int(5));
weak_ptr wp1(p1);//绑定操作

判断操作中会用到函数lock()    如果指向的内存不为空返回一个与之内存对应的shared_ptr,反之返回空的shared_ptr

if(shared_ptr ptmp=wp1.lock())//为空就不会进入函数体中了
{...}

 

你可能感兴趣的:(学习笔记)