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. 【转帖】浅析经典JVM垃圾收集器-Serial/ParNew/Parallel Scavenge/Serial Old/Parallel Old/CMS/G1

    https://zhuanlan.zhihu.com/p/481256418 在讲述垃圾收集器之前,我们得先知道JVM中常见的垃圾收集算法有什么,具体请参考我的这篇博文.如果说收集算法是内存回收的方法 ...

  2. Python学习之八_调用Outlook发送邮件以及调用远程windows上面的python

    Python学习之八_调用Outlook发送邮件以及调用远程windows上面的python 摘要 之前只有一个需求是发送加密邮件. 之前一直是使用linux进行发送.但是总是无法发送加密邮件. 最近 ...

  3. 【AIGC】只要10秒,AI生成IP海报,解放双手!!!

    看完这篇文章,你将学会以下价值连城的内容 1.云端部署(配置不行的小伙伴看)+ 云端模型放置位置 2.本地部署(配置达标的小伙伴看) 3.运用SD训练IP的流程和技巧(LoRA篇) 4.运用SD稳定生 ...

  4. 【图论,网络流】CF1525F Goblins And Gnomes

    Problem Link 你在打怪.你有一个 \(n\) 个点 \(m\) 条边的 DAG,接下来会有 \(k\) 波怪来袭,第 \(i\) 波怪有 \(i\) 个,它们会各自选择走一条路径,要求它们 ...

  5. 在web中,用户输入的文字过多 和页面排版一行显示不下 怎么办

    在写管理系统中, 如果用户在input中,表单输入过多,应该如何去处理 常用的解决办法是: 1==>用户只能够输入一定范围内的字数 2==>超出几个字后(宽度)使用省略号显示. 3==&g ...

  6. python中,Microsoft Visual C++ 14.0 or greater is required问题解决方案

    今天在写一个小程序,安装依赖的时候发现这个问题,平时都是直接安装Visual Studio解决,但是这个安装太大了,所以解决看看怎么安装是最方便的,最容易解决的. 下面这个就是出现的问题: build ...

  7. linux虚拟机固定ip

    1.查看宿主机IP信息 在windows宿主机上,键盘输入win+r,输出cmd,打开终端命令行: 输入ipconfig /all,查看宿主机IP信息: 2.修改Linux虚拟机的配置文件 Linux ...

  8. 有道云笔记之备选方案Obsidian和Notion

    有道云笔记限制登录设备 在商业项目中一般都会有plana.planb,对于云笔记,我也在寻找planb,有道云笔记在国内市场已经占据了很大的份额. 同类型中的就不再去挑选了,我觉得商业软件,迟早也会走 ...

  9. mac接入两根网线

    mac机接了USB扩展槽之后,扩展槽可以接入一根网线,机器自带一个网线口,这样就可以同时接入两根网线,为什么要这样做? 因为我所在的公司是分内外网的,研发的机器是内网环境,而打包机有时候需要联网,那么 ...

  10. PaddleNLP通用信息抽取技术UIE【一】产业应用实例:信息抽取{实体关系抽取、中文分词、精准实体标。情感分析等}、文本纠错、问答系统、闲聊机器人、定制训练

    相关文章: 1.快递单中抽取关键信息[一]----基于BiGRU+CR+预训练的词向量优化 2.快递单信息抽取[二]基于ERNIE1.0至ErnieGram + CRF预训练模型 3.快递单信息抽取[ ...