跳转到主要内容
模块 7 · 第 2 课(共 2)课程中的16/18~12 min
模块课程(2/2)

std::weak_ptr

尽管 std::shared_ptr 非常有用,但仅依赖共享所有权可能会导致称为“循环引用”(或循环依赖)的问题。

如果两个或多个对象各自包含指向另一个的 shared_ptr ,则会创建一个闭环。在这种情况下,两个对象的引用计数都不会达到零,从而防止释放并导致内存泄漏。

什么是 std::weak_ptr

为了打破所有权周期,标准库提供了 std::weak_ptr。这是一个智能指针,它观察由 shared_ptr 管理的对象,但不增加引用计数。

它不直接拥有该资源,因此不会阻止其销毁。

C++
#include <memory>

std::shared_ptr<int> shared = std::make_shared<int>(42);
std::weak_ptr<int> weak = shared; // Does not increment reference count!

验证和访问资源

由于 weak_ptr 不拥有该资源,因此可以随时释放该资源(当所有关联的 shared_ptr 实例超出范围时)。

要使用观察到的资源,我们必须:

  1. 使用 expired() 检查它是否仍然有效。
  2. 使用 lock() 方法临时将 weak_ptr 转换为 shared_ptr。如果资源仍处于活动状态,则 lock() 返回有效的 shared_ptr,否则返回空指针 (nullptr)。
C++
if (!weak.expired()) {
    // lock() creates a temporary shared_ptr to ensure safe access
    if (std::shared_ptr<int> sharedAccess = weak.lock()) {
        std::cout << *sharedAccess << std::endl;
    }
} else {
    std::cout << "Resource deallocated!" << std::endl;
}

自己尝试一下

锻炼#cpp.m7.l2.e1
尝试:0加载中...

声明一个从 sPtr 初始化的名为 wPtr 的 std::weak_ptr<int> 。然后使用 std::cout 打印 wPtr.expired() 返回的布尔结果。

正在加载编辑器...
显示提示

声明表示相同泛型类型“<int>”的“weak_ptr”,并将“sPtr”直接分配给它。

3 次尝试后可用的解决方案

锻炼#cpp.m7.l2.e2
尝试:0加载中...

使用wPtr上的lock()方法来获取临时的shared_ptr。如果操作成功(指针不为空),则打印取消引用的值。

正在加载编辑器...
显示提示

通过调用“wPtr.lock()”初始化“if”块内的变量,然后打印使用星号“*”取消引用它的资源。

3 次尝试后可用的解决方案