《Effective Modern C++》学习笔记之条款二十:对于类似std::shared_ptr但有可能空悬的指针使用std::weak_ptr

本文解析了std::weak_ptr的基本概念,强调其不会增加std::shared_ptr引用计数的特点,并介绍了如何安全地检查和获取std::shared_ptr的状态。重点讨论了多线程环境下的使用注意事项和两种获取强引用的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

std::weak_ptr(r弱共享指针)一般使用std::shared_ptr来创建,且它的尺寸和创建它的std::shared_ptr对象尺寸相同,也和std::shared_ptr对象有着相同的控制块。

但std::weak_ptr的创建并不会增加std::shared_ptr的引用计数,而只会增加其自身的引用计数,这部分内容将会在下节继续介绍:

auto spw = std::make_shared<Widget>();

//spw的引用计数并不会增大
std::weak_ptr wpw(spw);

此时若spw被析构,则wpw将空悬,我们可以使用std::weak_ptr的成员函数expired()进行判断。但expired()是非原子操作,所以在多线程编程中,其结果不一定准确:在expired()函数被调用后,另一个线程立即析构std::shared_ptr对象,所以在expired()条件下的处理都是有风险的。

auto spw = std::make_shared<Widget>();

//spw的引用计数并不会增大
std::weak_ptr wpw(spw);

if (wpw.expired()) {
    // .... 
}

这里提供两种安全获取std::shared_ptr状态的方法:

auto spw = std::make_shared<Widget>();

//spw的引用计数并不会增大
std::weak_ptr wpw(spw);

// 第一种
// 若wpw失效,则spw1结果为nullptr,不会出现访问空指针的情况
// 若wpw未失效,则该操作将std::shared_ptr引用计数+1,保证访问期间不会析构
std::shared_ptr<Widget>spw1 = wpw.lock(); 

//第二种
//若wpw失效,将抛出异常,否则将引用计数+1,保证访问期间不会析构
std::shared_ptr<Widget> spw3(wpw);

 注意:对于std::shared_ptr的控制块,只有当其std::weak_ptr的引用次数为0时才会被释放。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chiang木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值