1.继承自Ptr_base¶
![[Pasted image 20250222091857.png]] 干嘛的?
ptr_base两个成员:¶
- Ptr:指向实际管理的对象
- Rep:指向控制块(包含引用计数、分配器等元数据)。 还有些友元类,可以供自己同类型的对象,子shared_Ptr对象,原子结构....直接调用私有变量。
![[Pasted image 20250222092356.png]]
删除拷贝构造与赋值构造¶
![[Pasted image 20250222093404.png]]
对象的删除(纯虚函数)¶
![[Pasted image 20250222094125.png]] 意识就是说智能指针的删除还得让子类自己来实现
use_count引用计数¶
这个_Rep究竟怎么计数的?
![[Pasted image 20250222092758.png]]
先找到这个类型:法线里面有两个原子类型的计数器。也就是说自带一个强引用和弱引用
- _Uses
= 1
- _Weaks
= 1
![[Pasted image 20250222092942.png]]
![[Pasted image 20250222093430.png]]
![[Pasted image 20250222093450.png]]
_Incref_nz()
:非零时安全递增引用计数(原子读取,CAS)_Incref()
:增加强引用计数Incwref()
:增加弱引用计数_Decref
:减少强引用计数,强引用为0,还要减少弱引用,还要destroy_Decwref
:减少弱引用,弱引用为0,deletethis删除控制块自身use_count
:一个静态转换。_Get_deleter
:或得删除器的一个虚函数
2.Shared_Ptr部分¶
基类取别名¶
![[Pasted image 20250223103739.png]]
构造¶
- 使用默认构造
- 然后是一系列带参数的构造
- 空指针
- 裸指针:
- 数组类型:加个数组删除器
- 非数组:用新的类型管理指针,创建引用块控制块
- 带删除器的构造:删除器需可移动构造
- 带删除器和分配器的构造:分配器用于分配控制块资源
- 别名构造函数:与别名共享控制块,但指向不同变量
- 作用:如指向派生类的基类成员,但不影响原始引用计数
- 别名移动构造函数:
- 拷贝构造函数: 增加引用计数,共享同一控制块
- 移动构造函数:转移资源所有权,原shared_ptr变为空
- 从weak_ptr构造:
- 先判断weak_ptr是否过期,构造一个共享资源的share_ptr
- 过期了则抛出bad_weak_ptr
- auto_ptr构造:
- 直接获取、转换、释放
- 注意auto_ptr已经被弃用了,这个构造函数仅为兼容性保留
- 从uniqur_ptr进行构造:
- 先获取unique_ptr的指针
- 再获取unique_ptr的删除器
- 要确保删除器类型兼容shared_ptr
- 将unique_ptr转换过来
- 释放unqire_ptr的指针
- 析构函数
- 调用的是基类的减少引用Decref的方法。
- 减少引用,计数归零则释放资源
内部方法¶
swap():¶
智能指针先禁用了标准库std特化的swap,使用的是concepts库range的swap - ADL检查概念:先判断对象是类或枚举,避免对基本类型触发ADL --> - 定制点对象: - 使用ADL找到的Swap,即用户为自定义类定义了swap - 通用移动交换:经典三次移动交换 - 移动构造临时对象tmp - 移动赋值x = y - 移动赋值y = tmp - 数组交换 -
reset¶
- unique():如果use_count = 1就返回
友元方法¶
- make_shared
- allocate_shared
指针转换¶
这些本质上都是cast<_Ty*>
的处理,然后再重新进行一次构造
- static_pointer_cast:支持静态类型转换(如基类和派生类)
- const_pointer_cast:移除或添加const限定符
- reinterpret_pointer_cast:强制转换,二进制层面的指针转换(如void*)
仅在RTTI启用时有用
- dynamic_pointer_cast:支持运行时类型检查
- cast<_Ty*>
的处理
- 转换成功返回shared_Ptr,失败则返回nullptr
重载运算符¶
get
- *
- ()
- []
赋值¶
![[Pasted image 20250223113619.png]] - 拷贝赋值:纯粹的swap - 模板化拷贝赋值(支持类型转换):与普通拷贝赋值相同,但支持非法类型转换 - 能使Ty2 可安全转换为 Ty(例如派生类到基类) - enable_if:限制模版实例化,避免非法类型转换 - 移动赋值:转移资源所有权,原指针变为空 - move将左值转换为右值引用对象后,调用移动构造,构造临时右值引用对象,(将right的资源转移过来,原right置空) - 交换,原资源由临时对象析构时释放 - 模板化移动赋值 - auto_ptr的赋值: - 移动语义,构造一遍 - 交换 - unique_ptr的赋值 - 捕获删除器,并将其存储到控制块中 - 移动 - 交换