std::weak_ptr的核心作用是打破shared_ptr的循环引用并安全观察对象存续状态;它不参与引用计数,通过lock()临时升级为shared_ptr访问对象,或用expired()判断是否已销毁。

std::weak_ptr 的核心作用是打破 shared_ptr 的循环引用,同时安全地观察一个由 shared_ptr 管理的对象是否还存在。 它不参与对象的引用计数,因此不会延长对象生命周期,但能临时“升级”为 shared_ptr 来访问对象(前提是对象还没被销毁)。
为什么需要 weak_ptr?—— 循环引用问题
当两个对象互相用 shared_ptr 持有对方时,它们的引用计数永远 ≥1,导致析构无法触发,内存泄漏。
例如:
- A 中有个 shared_ptr 指向 B
- B 中也有个 shared_ptr 指向 A
- 即使外部所有 shared_ptr 都离开作用域,A 和 B 的引用计数仍为 1,彼此“锁死”
weak_ptr 怎么破局?—— 不增加引用计数
把其中一端(通常是“从属关系”或“反向引用”)换成 weak_ptr:
立即学习“C++免费学习笔记(深入)”;
- 它持有控制块(control block)的指针,但不增加 strong count
- 调用 lock() 可尝试获取 shared_ptr:成功说明对象还在;失败(返回空)说明已被释放
- 使用 expired() 可快速判断对象是否已销毁,避免每次 lock() 再检查
典型使用场景
除了破循环,weak_ptr 还适合这些情况:
- 缓存/观察者模式:缓存中存 weak_ptr,用时 lock(),若为空就重建或跳过
- 父子关系管理:子对象用 weak_ptr 指向父对象(避免父无法释放)
- 定时器或异步回调:回调里用 weak_ptr 检查宿主对象是否还活着,防止访问已析构对象
一个小提醒
weak_ptr 本身不能直接解引用(没有 operator-> 或 operator*),必须先 lock() 成 shared_ptr 才能安全访问。这其实是它的保护机制——强制你面对对象可能已不存在的事实。
基本上就这些。不复杂,但容易忽略。











