std::shared_ptr<int> a = std::make_shared<int>(2);
std::weak_ptr<int> b = a;
a = nullptr;
if (std::shared_ptr<int> b_lock = b.lock())
std::cout << *b_lock;
else
std::cout << "b is null\n";

上面结果打印 "b is null"

weak_ptr 不进行计数,并且不能操作内存,当前赋值的 shared_ptr 销毁后,weak_ptr 也会置空

weak_ptr works together with shared_ptr. When using both, it's still true that the object the pointers point at normally gets destroyed as soon as and only when no shared_ptr points at it any more.

But also, when that object is destroyed, any weak_ptr pointers which were pointing at it automatically change to act like null pointers.

The b.lock() call and shared_ptr b_lock are needed because you can't use a weak_ptr directly, as with *b. This is a safety feature, because if you wrote code to check that b is not null and then

later uses *b, what if some function you call between the check and the use (or some other thread!) happens to destroy or change a? Instead we use lock() to convert the weak_ptr back to a local 

shared_ptr, check whether that pointer is null, and use the shared_ptr. The local shared_ptr guarantees the object will continue living long enough for the code that's about to use it, but doesn't need to stick around after that.

有关其他智能指针的使用可以参阅:


weak_ptr 介绍:

weak_ptr 是一种不控制对象生命周期的智能指针, 它指向一个 shared_ptr 管理的对象. 进行该对象的内存管理的是那个强引用的 shared_ptr. weak_ptr只是提供了对管理对象的一个访问手段.

weak_ptr 设计的目的是为配合 shared_ptr 而引入的一种智能指针来协助 shared_ptr 工作, 它只可以从一个 shared_ptr 或另一个 weak_ptr 对象构造, 它的构造和析构不会引起引用记数的增加或减少.

weak_ptr 在功能上类似于普通指针, 然而一个比较大的区别是, 弱引用能检测到所管理的对象是否已经被释放, 从而避免访问非法内存。

weak_ptr 没有重载*和->但可以使用 lock 获得一个可用的 shared_ptr 对象

比如,

#include <iostream>

int main() {
auto shared = std::make_shared<int>(1); auto weak = std::weak_ptr<int>{shared};
auto w = weak; std::shared_ptr<int> ww = w.lock();
std::cout << std::boolalpha << "shared.use_count(): " << shared.use_count()
<< '\n'
<< "weak.use_count(): " << weak.use_count() << '\n'
<< "weak.expired(): " << weak.expired() << '\n'
<< "w.use_count(): " << w.use_count() << '\n'; shared.reset(); std::cout << "weak.reset();\n"
<< "shared.use_count(): " << shared.use_count() << '\n'
<< "weak.use_count(): " << weak.use_count() << '\n'
<< "weak.expired(): " << weak.expired() << '\n'
<< "w.use_count(): " << w.use_count() << '\n'
<< "w is " << *ww << '\n'; std::shared_ptr<int> a = std::make_shared<int>(2);
std::weak_ptr<int> b = a;
a = nullptr;
if (std::shared_ptr<int> b_lock = b.lock()) {
std::cout << *b_lock << std::endl;
} else {
std::cout << "b is null\n";
}
} 

结果,

注意: 虽然通过弱引用指针可以有效的解除循环引用, 但这种方式必须在程序员能预见会出现循环引用的情况下才能使用, 也可以是说这个仅仅是一种编译期的解决方案, 如果程序在运行过程中出现了循环引用, 还是会造成内存泄漏.

关于垃圾回收的讨论:

std::weak_ptr 与 std::shared_ptr 配合使用的更多相关文章

  1. Item 20: 使用std::weak_ptr替换会造成指针悬挂的类std::shared_ptr指针

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 矛盾的是,我们很容易就能创造出一个和std::shared_ptr ...

  2. std::shared_ptr 和 std::weak_ptr的用法以及引用计数的循环引用问题

    在std::shared_ptr被引入之前,C++标准库中实现的用于管理资源的智能指针只有std::auto_ptr一个而已.std::auto_ptr的作用非常有限,因为它存在被管理资源的所有权转移 ...

  3. 智能指针std::weak_ptr

    std::weak_ptr 避免shared_ptr内存泄漏的利器.

  4. std::weak_ptr

    weak_ptr 是一种不控制对象生命周期的智能指针, 它指向一个 shared_ptr 管理的对象. 进行该对象的内存管理的是那个强引用的 shared_ptr. weak_ptr只是提供了对管理对 ...

  5. Item 21: 比起直接使用new优先使用std::make_unique和std::make_shared

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 让我们先从std::make_unique和std::make_s ...

  6. 深入学习c++--智能指针(二) weak_ptr(打破shared_ptr循环引用)

    1. 几种智能指针 1. auto_ptr: c++11中推荐不使用他(放弃) 2. shared_ptr: 拥有共享对象所有权语义的智能指针 3. unique_ptr: 拥有独有对象所有权语义的智 ...

  7. C++11 使用异步编程std::async和std::future

    先说明一点:std::asyanc是std::future的高级封装, 一般我们不会直接使用std::futrue,而是使用对std::future的高级封装std::async. 下面分别说一下. ...

  8. 【C++并发实战】(三) std::future和std::promise

    std::future和std::promise std::future std::future期待一个返回,从一个异步调用的角度来说,future更像是执行函数的返回值,C++标准库使用std::f ...

  9. C++0x,std::move和std::forward解析

    1.std::move 1.1std::move是如何定义的 template<typename _Tp> constexpr typename std::remove_reference ...

  10. std::unique_lock与std::lock_guard分析

    背景 C++多线程编程中通常会对共享的数据进行写保护,以防止多线程在对共享数据成员进行读写时造成资源争抢,导致程序出现未定义或异常行为.通常的做法是在修改共享数据成员时进行加锁(mutex).在使用锁 ...

随机推荐

  1. [转帖]ORACLE 并行(PARALLEL)实现方式及优先级

      http://blog.itpub.net/25542870/viewspace-2120924/ 一.      Parallel query 默认情况下session 是ENABLE状态 1. ...

  2. [转帖]NVIDIA超级AI服务器NVIDIA DGX GH200性能介绍

    https://zhuanlan.zhihu.com/p/633219396 2023 年 5 月 28 日NVIDIA宣布推出 NVIDIA DGX GH200,这是首款 100 TB级别的GPU ...

  3. [转帖]SSL数字证书分类DV/OV/EV

    SSL证书的分类主要是通过下面两个维度进行分类: 1.根据验证模式分类 根据CA机构对申请者的身份审核范围分为:DV证书.OV证书.EV证书. 1.1.DV证书(域名证书) DV(Domain Val ...

  4. Oracle 核心列信息查看与处理

    Oracle 核心列信息查看与处理 背景 最近想对数据库表进行跨数据之间的比照 因为有一些自增列或者是时间戳的列不需要进行对比 后者是对比容易导致失真. 所以就准备选用其他方式进行一下处理. 本文主要 ...

  5. [转帖]总结:SpringBoot启动参数配置

    一.背景 由于项目中加了bootstrap.properties文件,且文件中有变量,如spring.cloud.config.profile=${spring.profiles.active},而b ...

  6. [转帖]Oracle 通过 Exadata 云基础设施 X9M 提供卓越的数据库性能和规模

    https://www.modb.pro/db/397202 32个节点的RAC 服务器 每个服务器 两个 64核心的AMD CPU 四个线程干管理 252个线程进行数据库处理 252*32=8064 ...

  7. OpenSSH 9.2P1升级以及版本显示的处理过程

    说明 本次维护的时间是 2023-2-9 最新已发布的补丁是 OpenSSH9.2P1版本 其他本本应该是类似处理. 下载介质 在 OpenSSH官网打开相关界面. http://www.openss ...

  8. 物联网浏览器(IoTBrowser)-Web串口自定义开发

    物联网浏览器(IoTBrowser)-Web串口自定义开发 工控系统中绝大部分硬件使用串口通讯,不论是原始串口通讯协议还是基于串口的Modbus-RTU协议,在代码成面都是使用System.IO.Po ...

  9. CDP技术系列(一):使用bitmap存储数十亿用户ID的标签或群体

    一.背景介绍 CDP系统中目前存在大量由用户ID集合组成的标签和群体,截止当前已有几千+标签,群体2W+. 大量的标签都是亿级别数据量以上,例如性别.职业.学历等均,甚至有群体中的ID数量达到了数十亿 ...

  10. 从一次CPU打满到ReDos攻击和防范

    作者:京东物流 刘海茂 近期碰到一起值班报警事件,web 应用服务器 CPU 消耗打到 99%,排查后发现是因为 ReDoS 导致了服务器发生了资源被耗尽.访问系统缓慢的问题,通过排查过程从而分享下 ...