共享指针——弱引用

智能指针

弱引用指针 —— weak_ptr

weak_ptr 是一种不拥有资源所有权的智能指针,它只对对象进行弱引用,不会影响对象的生命周期。
仅用来表示当前对象是否存在。

其主要特点如下:

  • 不参与引用计数,不会增加 shared_ptruse_count
  • 不拥有对象所有权,因此不能直接使用 -> 或解引用 *
  • 不能单独创建,必须依附于 shared_ptr 存在
  • 可通过 lock() 方法安全地转换为 shared_ptr

创建与类型转换

weak_ptr 通常由已有的 shared_ptr 创建,并用于观察对象的生命周期。

弱引用的创建与提升
int main()
{
    shared_ptr<cat> cat1 = make_shared<cat>("Tom");

    // 由 shared_ptr 创建 weak_ptr(不会增加引用计数)
    weak_ptr<cat> weak_cat1 = cat1;

    cout << weak_cat1.use_count() << endl; // 1
    cout << cat1.use_count() << endl;      // 1

    // 通过 lock() 将 weak_ptr 提升为 shared_ptr
    shared_ptr<cat> cat2 = weak_cat1.lock();

    cout << cat2.use_count() << endl;      // 2
}

说明:

  • lock() 会检查对象是否仍然存活
  • 若对象已被释放,lock() 返回一个空的 shared_ptr,避免悬空指针问题

典型应用场景

  1. 某个类(如 A 类)需要保存其他同类型对象的引用信息
  2. 如果直接使用 shared_ptr,多个对象之间容易形成循环引用(Cyclic Dependency)
  3. 为避免循环依赖,应使用不拥有所有权的引用关系
  4. weak_ptr 正是用于这种“仅引用、不管理生命周期”的场景
  5. 在需要访问对象时,可通过 lock() 临时获取 shared_ptr

weak_ptr 解决循环引用问题

当两个对象相互持有对方的 shared_ptr 时,会导致如下问题:

  • A 持有 B 的 shared_ptr
  • B 同时也持有 A 的 shared_ptr
  • 即使外部不再使用 A 或 B,它们的引用计数仍然不为 0
  • 导致对象无法析构,产生内存泄漏

这就是典型的循环引用问题

在下面的示例中,我们将 c3c4 互相设为“朋友”,并在两个类中都使用 shared_ptr 保存对方:

结果:对象可以被创建,但无法被销毁

image


使用 weak_ptr 的改进方案

将其中一方(或双方)对对方的引用:

  • shared_ptr 改为 weak_ptr

此时:

  • 引用关系仍然存在
  • 但不会影响对象的生命周期
  • 当外部 shared_ptr 释放后,对象即可正常析构

程序将恢复正常运行

image


一句话总结

  • shared_ptr 管理生命周期
  • weak_ptr 只负责观察,不拥有资源
  • 打破循环引用,必须引入 weak_ptr
posted @ 2025-12-24 22:23  Ytytyty  阅读(0)  评论(0)    收藏  举报