C++ 中的四种智能指针
引言:为什么需要智能指针?
C++赋予了程序员直接操控底层内存的能力,同时,也对程序员的能力提出了要求,必须要对申请的内存空间进行释放,而且释放时机也必须准确,否则就会出现内存泄露,useafterfree 等异常。寻找一种简单完美的方式解决这个问题一直是 C++程序员需要关注的,在 Android 平台上使用了 StrongPoint 的方式,相当于将原有的指针包装成一个类,通过对指针 reference 次数的管理来实现对应空间的准确释放,在 C++中则也使用了类似的方式,使用了智能指针类,通过引用计数来管理智能指针指向的内存空间,只有当指针引用计数为空时,才进行对象的销毁。
接下来,我们就来一起看看 C++的四种智能指针。
C++的四种智能指针
代码位置(参考 AOSP 代码)
基础接口
get()返回封装在内部的指针
operator*解引用原生指针
operator->相当于对原生指针做->操作
operator=指针拷贝操作
release 将内部封装的指针置为 nullptr,返回置空前的值
reset 将内部封装的指针重置为 ptr 的值
1.auto_ptr(C++98 的方案,C11 已抛弃)采用所有权模式
观察 auto_ptr 的赋值重载函数,会将等号右面的 point reset
auto_ptr 是独占的,当赋值之后,存在潜在的无法检测的内存异常。
2.unique_ptr
unique_ptr 实现独占式拥有或严格拥有概念,保证同一时间内只有一个智能指针可以指向该对象,主要为了避免资源泄露。上面的例子:
同样,我们来看看它的赋值重载函数,只发现了移动构造和移动赋值函数,正常的拷贝构造和赋值拷贝是被禁用的
3.shared_ptr(共享型,强引用)
shared_ptr 实现共享式拥有概念,多个智能指针可以指向相同对象,该对象和其相关资源会在“最后一个引用被销毁”时候释放。资源可以被多个指针共享,它使用计数机制来表明资源被几个指针共享。过成员函数 use_count() 来查看资源的所有者个数,调用 release() 时,当前指针会释放资源所有权,计数减一,当计数等于 0 时,资源会被释放。我们来看看其释放的过程:
4.weak_ptr(弱引用)
weak_ptr 是一种不控制对象生命周期的智能指针,它指向一个 shared_ptr 管理的对象。进行该对象的内存管理的是那个强引用的 shared_ptr。weak_ptr 设计的目的是为配合 shared_ptr 而引入的一种智能指针来协助 shared_ptr 工作,它只可以从一个 shared_ptr 或另一个 weak_ptr 对象构造,,它的构造和析构不会引起引用记数的增加或减少。
weak_ptr 是用来解决 shared_ptr 相互引用时的死锁问题,如果说两个 shared_ptr 相互引用,那么这两个指针的引用计数永远不可能下降为 0,也就是资源永远不会释放。当两个智能指针都是 shared_ptr 类型的时候,析构时两个资源引用计数会减一,但是两者引用计数还是为 1,导致跳出函数时资源没有被释放(的析构函数没有被调用),解决办法:把其中一个改为 weak_ptr 就可以。
版权声明: 本文为 InfoQ 作者【桑榆】的原创文章。
原文链接:【http://xie.infoq.cn/article/a70400858ccc37544f8053b40】。文章转载请联系作者。
评论