c++中的std::weak_ptr有什么用_c++解决shared_ptr循环引用问题【智能指针】

9次阅读

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

c++ 中的 std::weak_ptr 有什么用_c++ 解决 shared_ptr 循环引用问题【智能指针】

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 才能安全访问。这其实是它的保护机制——强制你面对对象可能已不存在的事实。

基本上就这些。不复杂,但容易忽略。

text=ZqhQzanResources