1.46、weak_ptr是怎么实现的?
实现原理
控制块(Control Block)
shared_ptr
和weak_ptr
都指向同一个控制块,该控制块维护两个计数器:
- • 强引用计数(
use_count
):当前有多少个shared_ptr
实例拥有对象所有权。 - • 弱引用计数(
weak_count
):当前有多少个weak_ptr
实例引用该控制块(不拥有对象所有权)。
对象生命周期管理
- • 当
shared_ptr
的最后一个实例销毁时,强引用计数归零,对象被释放。 - • 控制块本身只有当强引用计数和弱引用计数都为零时才被销毁。
weak_ptr不拥有对象
weak_ptr
仅持有对控制块的弱引用,不增加强引用计数,不影响对象生命周期。
它可以观察对象是否还存活,但不控制对象销毁。
关键方法与行为
构造和赋值
- •
weak_ptr
可以从shared_ptr
构造,内部增加弱引用计数。 - • 复制或赋值
weak_ptr
也会增加弱引用计数。
检测对象有效性
- •
expired()
:判断对象是否已被销毁(即强引用计数是否为0)。 - •
use_count()
:返回当前强引用计数。
获取临时所有权
- •
lock()
:尝试从weak_ptr
获得一个临时的shared_ptr
,如果对象仍然存在(强引用计数>0),返回有效的shared_ptr
;否则返回空指针。 - •
lock()
操作是线程安全的,保证在多线程环境下不会产生竞态条件。
作用与优势
解决循环引用
在两个对象互相持有shared_ptr
时,会导致引用计数永远不为零,造成内存泄漏。
使用weak_ptr
打破循环引用链,避免资源无法释放。
避免悬挂指针
通过weak_ptr
观察对象状态,避免访问已被销毁的对象,减少悬挂指针风险。
线程安全的临时访问
多线程环境下,weak_ptr
能安全地检测对象是否存活并获取临时所有权。
简要示意图
shared_ptr<T> ---+
| 控制块(use_count, weak_count)
weak_ptr<T> -----+
- use_count:shared_ptr数量
- weak_count:weak_ptr数量(不含shared_ptr)
总结
std::weak_ptr
通过共享控制块中的弱引用计数实现对对象的非拥有性观察,避免循环引用导致的内存泄漏,并提供线程安全的方式获取临时所有权。它是shared_ptr
的辅助工具,适用于需要观察对象生命周期但不参与所有权管理的场景。
本文首发于【讳疾忌医-note】公众号,未经授权,不得转载。
(加入我的知识星球,免费获取账号,解锁所有文章。)
阅读剩余
版权声明:
作者:讳疾忌医-note
链接:https://www.1217zy.vip/archives/1340
文章版权归作者所有,未经允许请勿转载。
THE END