共享指针——弱引用
智能指针
弱引用指针 —— weak_ptr
weak_ptr 是一种不拥有资源所有权的智能指针,它只对对象进行弱引用,不会影响对象的生命周期。
仅用来表示当前对象是否存在。
其主要特点如下:
- 不参与引用计数,不会增加
shared_ptr的use_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,避免悬空指针问题
典型应用场景
- 某个类(如 A 类)需要保存其他同类型对象的引用信息
- 如果直接使用
shared_ptr,多个对象之间容易形成循环引用(Cyclic Dependency) - 为避免循环依赖,应使用不拥有所有权的引用关系
weak_ptr正是用于这种“仅引用、不管理生命周期”的场景- 在需要访问对象时,可通过
lock()临时获取shared_ptr
weak_ptr 解决循环引用问题
当两个对象相互持有对方的 shared_ptr 时,会导致如下问题:
- A 持有 B 的
shared_ptr - B 同时也持有 A 的
shared_ptr - 即使外部不再使用 A 或 B,它们的引用计数仍然不为 0
- 导致对象无法析构,产生内存泄漏
这就是典型的循环引用问题。
在下面的示例中,我们将 c3 和 c4 互相设为“朋友”,并在两个类中都使用 shared_ptr 保存对方:
结果:对象可以被创建,但无法被销毁

使用 weak_ptr 的改进方案
将其中一方(或双方)对对方的引用:
- 从
shared_ptr改为weak_ptr
此时:
- 引用关系仍然存在
- 但不会影响对象的生命周期
- 当外部
shared_ptr释放后,对象即可正常析构
程序将恢复正常运行:

一句话总结
shared_ptr管理生命周期weak_ptr只负责观察,不拥有资源- 打破循环引用,必须引入
weak_ptr

浙公网安备 33010602011771号