0.前言
C++ 标准模板库 STL(Standard Template Library) 一共给我们提供了四种智能指针:auto_ptr、unique_ptr、shared_ptr 和 weak_ptr,其中 auto_ptr 是 C++98 提出的,C++11 已将其摒弃,并提出了 unique_ptr 替代 auto_ptr。
1.shared_ptr
1.1设计原理
多个shared_ptr可以指向同一个对象,当最后一个shared_ptr在作用域范围内结束时,对象才会被自动释放。
1.2shared_ptr原理
- 一个shared_ptr会对一个对象产生强引用(strong reference)
- 每个对象都有个与之对应的强引用计数,记录着当前对象被多少个shared_ptr强引用着。可以通过shared_ptr的use_count函数获得强引用计数
- 当有一个新的shared_ptr指向对象时,对象的强引用计数就会+1
- 当有一个shared_ptr销毁时(比如作用域结束),对象的强引用计数就会-1
- 当一个对象的强引用计数为0时(没有任何的shared_ptr指向对象时),对象就会自动销毁(析构)
如下所示:
分别创建四个shared_ptr指针指向同一个对象,每次调用后强引用的次数+1,最后p4销毁后才析构
1.3思考题
这样的代码存在问题,在第一次智能指针被销毁时,对象的强引用次数为0,此时p析构了。
1.4shared_ptr的循环引用
如图当两个智能指针指向对方时,作用域结束后指针销毁,对象不会自动析构
此时需要用到weak_ptr来解决这个问题
2.weak_ptr
-
weak_ptr会对一个对象产生弱引用
-
weak_ptr可以指向对象解决shared_ptr的循环引用问题
此时的内存图如图:
当栈空间的智能指针销毁时,堆空间的Person对象强引用次数为0,Car对象的强引用次数为1,Person先析构,然后Car强引用次数为0,Car析构
3.unique_ptr
- unique_ptr也会对一个对象产生强引用,它可以确保同一时间只有1个指针指向对象
- 当unique_ptr销毁时(作用域结束时),其指向的对象也就自动销毁了
- 可以使用std:move函数转移unique_ptr的所有权
好了,对于智能指针的初步的学习就结束了!