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. [转帖]Kafka的Topic配置详解

    https://www.jianshu.com/p/c9a54a587f0e 一.Kafka中topic级别配置 配置topic级别参数时,相同(参数)属性topic级别会覆盖全局的,否则默认为全局配 ...

  2. [转帖]oracle中Rman增量备份下各级别level的区别

    RMAN备份分为全备和增量备份两部分 增量备份:分为0 1 2级 ORACLE官方解释:  A level 1 incremental backup can be either of the foll ...

  3. tidb备份恢复的方式方法

    tidb备份恢复的方式方法 摘要 可以单独每个数据库实例进行备份,但是这种机制实在是太慢了. 网上查资料发现可以使用 tiup br 的方式进行备份. 但是大部分文档都比较陈旧, 官网上面又比较贴心的 ...

  4. [转帖]性能测试工具netperf安装使用

    https://blog.51cto.com/dingtongxue1990/1853714 netperf工具使用 一.安装 1,下载 liunx下载地址:ftp://ftp.netperf.org ...

  5. [转帖] 容器内的Linux诊断工具0x.tools

    https://www.cnblogs.com/codelogs/p/16242999.html 原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介# Linux上有 ...

  6. 关于IO性能的一些学习与了解

    关于IO性能的一些学习与了解 摘要 最近心气不高. 学习进度也拖的比较慢. 以后想能够多为自己着想.自己有自己的节奏, 不能只为别人考虑. 要改变一下自己的做事风格. 一些事情想帮则帮, 不想帮就当看 ...

  7. 神经网络优化篇:详解为超参数选择合适的范围(Using an appropriate scale to pick hyperparameters)

    为超参数选择合适的范围 假设要选取隐藏单元的数量\(n^{[l]}\),假设,选取的取值范围是从50到100中某点,这种情况下,看到这条从50-100的数轴,可以随机在其取点,这是一个搜索特定超参数的 ...

  8. 【团队效率提升】Python-PyWebIO介绍

    作者:京东零售 关键 Q&A快速了解PyWebIO Q:首先,什么是PyWebIO? A:PyWebIO提供了一系列命令式的交互函数,能够让咱们用只用Python就可以编写 Web 应用, 不 ...

  9. JavaScript一种新的数据结构类型Map

    什么是map 它类似于对象,是键值对的集合,但键的范围不局限在于字符串.各种类型的值(包含对象)都可以作为键. 如果同一个键被多次赋值,后面的值将会覆盖其那面的值.如果读取一个未知的键,返回的是und ...

  10. 从零开始配置 vim(3)—— 键盘映射进阶

    严格意义上来说,快捷键的绑定应该是键盘映射,将某些键映射为另一些键. 在上篇我们介绍了基本的键盘映射操作,知道了如何 :map.:imap.:vmap.:nmap这些命令来映射键盘快捷键.它们很方便, ...