一.智能指针的使用场景分析
看下面代码:

正常执行流程:

执行顺序:

最后内存全部释放,没有问题
抛异常:

运行过程:

程序不会继续执行:

于是:

传统解决方案:try-catch 手动释放:

这里:
负责异常时释放资源
但问题来了:
new 自己也可能异常

可能:

还是泄露
智能指针解决问题:
使用:

执行顺序:

无内存泄露
本质:RAII 思想
资源跟对象生命周期绑定。
对象创建:

获得资源
对象销毁:

自动释放资源
二.RAII和智能指针的设计思路
1.RAll概念
RAII 全称:
Resource Acquisition Is Initialization
资源获取即初始化
用人话说就是:
资源和对象绑定,对象活着资源就有效,对象销毁自动释放资源。

这里的资源不限于内存
例如:

都可以用RAll
2.RAll的优点
先看传统写法:
管理动态内存:

问题:
如果中间

执行不到:

就泄露
RAII 的做法:
把资源交给对象。
例如:

使用:

执行顺序:

资源自动释放
3.RAII 的本质
利用对象生命周期。
对象:

所以从谁申请谁释放,变为谁管理谁释放

4.智能指针应用RAll
普通 RAII 只能自动释放。
但智能指针目标还有:
像普通指针一样好用
所以:
除了析构释放。
还要支持访问资源。
因此重载运算符.
1.operator*
解引用
普通指针:

智能指针:

使用:

等价:

输出:10
2.operator->
访问成员。
普通:

智能指针:

使用:

实际:

编译器自动展开
3.operator\[\]
支持数组
例如:

使用:

等价:

5.完整思路

使用:

三.C++标准库智能指针的使⽤
1.为什么会有多种智能指针
核心问题:
智能指针如何处理拷贝?
普通指针:

结果:

两个指针管理同一块资源
最后:

重复释放
崩溃。
不同智能指针就是解决这个问题的方法不同。
2.auto_ptr
特点:
拷贝=转移所有权
例子:

发生:

底层类似:
但:

就会崩溃,因为空指针访问
所以:

3.unique_ptr
规则:一个资源只能一个主人
支持移动,但不支持拷贝

只能:

结果:

使用场景:
资源独占
单对象管理
性能优先
4.shared_ptr
支持移动拷贝
底层:
引用计数
例子:

结构:

释放:
5.weak_ptr(辅助指针)
它:
不拥有资源
不增加引用计数
不释放资源
例如:

结果:

计数:1
不是2
作用:
解决循环引用。
例如:

当pb和pa需要建立关系时

计数永远是 1
释放不了
改成:

即可
6.默认delete
智能指针析构:
类似:

所以:
只能管理:

产生的资源
错误:

析构:

程序就会崩溃
7.删除器(Deleter)
解决释放方式不同。
例如文件:

不能:

要:

写法:

析构:

8.make_shared
普通:

推荐:

效果:

优点:
效率高
异常安全
代码简洁
9. operator bool
支持:

例如:

本质:
