模块 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 实例超出范围时)。
要使用观察到的资源,我们必须:
- 使用
expired()检查它是否仍然有效。 - 使用
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 次尝试后可用的解决方案