[C++11]弱引用智能指针weak_ptr初始化和相关的操作函数

2023-11-05

弱引用智能指针 std::weak_ptr 可以看做是 shared_ptr 的助手,它不管理 shared_ptr 内部的指针。std::weak_ptr 没有重载操作符 * 和 ->,因为它不共享指针,不能操作资源,所以它的构造不会增加引用计数,析构也不会减少引用计数,它的主要作用就是作为一个旁观者监视 shared_ptr 中管理的资源是否存在。

1.初始化

// 默认构造函数
constexpr weak_ptr() noexcept;
// 拷贝构造
weak_ptr (const weak_ptr& x) noexcept;
template <class U> weak_ptr (const weak_ptr<U>& x) noexcept;
// 通过shared_ptr对象构造
template <class U> weak_ptr (const shared_ptr<U>& x) noexcept;

/*作者: 苏丙榅
链接: https://subingwen.cn/cpp/weak_ptr/#1-%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95
来源: 爱编程的大丙*/

在 C++11 中,weak_ptr 的初始化可以通过以上提供的构造函数来完成初始化,具体使用方法如下:

#include <iostream>
#include <memory>
using namespace std;

int main() 
{
    shared_ptr<int> sp(new int);

    weak_ptr<int> wp1;
    weak_ptr<int> wp2(wp1);
    weak_ptr<int> wp3(sp);
    weak_ptr<int> wp4;
    wp4 = sp;
    weak_ptr<int> wp5;
    wp5 = wp3;
    
    return 0;
}

/*作者: 苏丙榅
链接: https://subingwen.cn/cpp/weak_ptr/#1-1-%E5%88%9D%E5%A7%8B%E5%8C%96
来源: 爱编程的大丙*/
  • weak_ptr wp1; 构造了一个空 weak_ptr 对象

  • weak_ptr wp2(wp1); 通过一个空 weak_ptr 对象构造了另一个空 weak_ptr 对象

  • weak_ptr wp3(sp); 通过一个 shared_ptr 对象构造了一个可用的 weak_ptr 实例对象

  • wp4 = sp; 通过一个 shared_ptr 对象构造了一个可用的 weak_ptr 实例对象(这是一个隐式类型转换)

  • wp5 = wp3; 通过一个 weak_ptr 对象构造了一个可用的 weak_ptr 实例对象

其他常用方法

  • use_count()

通过调用 std::weak_ptr 类提供的 use_count() 方法可以获得当前所观测资源的引用计数,函数原型如下:

// 函数返回所监测的资源的引用计数
long int use_count() const noexcept;

修改一下上面的测试程序,添加打印资源引用计数的代码:

#include <iostream>
#include <memory>
using namespace std;

int main() 
{
    shared_ptr<int> sp(new int);

    weak_ptr<int> wp1;
    weak_ptr<int> wp2(wp1);
    weak_ptr<int> wp3(sp);
    weak_ptr<int> wp4;
    wp4 = sp;
    weak_ptr<int> wp5;
    wp5 = wp3;

    cout << "use_count: " << endl;
    cout << "wp1: " << wp1.use_count() << endl;
    cout << "wp2: " << wp2.use_count() << endl;
    cout << "wp3: " << wp3.use_count() << endl;
    cout << "wp4: " << wp4.use_count() << endl;
    cout << "wp5: " << wp5.use_count() << endl;
    return 0;
}

测试程序输出的结果为:

在这里插入图片描述

通过打印的结果可以知道,虽然弱引用智能指针 wp3、wp4、wp5 监测的资源是同一个,但是它的引用计数并没有发生任何的变化,也进一步证明了 weak_ptr只是监测资源,并不管理资源。

  • expired()

通过调用 std::weak_ptr 类提供的 expired() 方法来判断观测的资源是否已经被释放,函数原型如下:

// 返回true表示资源已经被释放, 返回false表示资源没有被释放
bool expired() const noexcept;

函数的使用方法如下:

#include <iostream>
#include <memory>
using namespace std;

int main() 
{
    shared_ptr<int> shared(new int(10));
    weak_ptr<int> weak(shared);
    cout << "1. weak " << (weak.expired() ? "is" : "is not") << " expired" << endl;

    shared.reset();
    cout << "2. weak " << (weak.expired() ? "is" : "is not") << " expired" << endl;

    return 0;
}

测试代码输出的结果:
在这里插入图片描述

weak_ptr 监测的就是 shared_ptr 管理的资源,当共享智能指针调用 shared.reset(); 之后管理的资源被释放,因此 weak.expired() 函数的结果返回 true,表示监测的资源已经不存在了。

  • lock()

通过调用 std::weak_ptr 类提供的 lock() 方法来获取管理所监测资源的 shared_ptr 对象,函数原型如下:

shared_ptr<element_type> lock() const noexcept;

函数的使用方法如下:

#include <iostream>
#include <memory>
using namespace std;

int main()
{
    shared_ptr<int> sp1, sp2;
    weak_ptr<int> wp;

    sp1 = std::make_shared<int>(520);
    wp = sp1;
    sp2 = wp.lock();
    cout << "use_count: " << wp.use_count() << endl;

    sp1.reset();
    cout << "use_count: " << wp.use_count() << endl;

    sp1 = wp.lock();
    cout << "use_count: " << wp.use_count() << endl;

    cout << "*sp1: " << *sp1 << endl;
    cout << "*sp2: " << *sp2 << endl;

    return 0;
}

测试代码输出的结果为:

在这里插入图片描述

  • sp2 = wp.lock(); 通过调用 lock() 方法得到一个用于管理 weak_ptr
    对象所监测的资源的共享智能指针对象,使用这个对象初始化 sp2,此时所监测资源的引用计数为 2

  • sp1.reset(); 共享智能指针 sp1 被重置,weak_ptr 对象所监测的资源的引用计数减 1

  • sp1 = wp.lock();sp1 重新被初始化,并且管理的还是 weak_ptr 对象所监测的资源,因此引用计数加 1

  • 共享智能指针对象 sp1 和 sp2 管理的是同一块内存,因此最终打印的内存中的结果是相同的,都是 520


  • reset()

通过调用 std::weak_ptr 类提供的 reset() 方法来清空对象,使其不监测任何资源,函数原型如下:

void reset() noexcept;

函数的使用是非常简单的,示例代码如下:

#include <iostream>
#include <memory>
using namespace std;

int main() 
{
    shared_ptr<int> sp(new int(10));
    weak_ptr<int> wp(sp);
    cout << "1. wp " << (wp.expired() ? "is" : "is not") << " expired" << endl;

    wp.reset();
    cout << "2. wp " << (wp.expired() ? "is" : "is not") << " expired" << endl;

    return 0;
}

测试代码输出的结果为:

在这里插入图片描述

weak_ptr 对象 sp 被重置之后 wp.reset(); 变成了空对象,不再监测任何资源,因此 wp.expired() 返回 true

转载链接:

https://subingwen.cn/cpp/weak_ptr/#1-2-4-reset

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[C++11]弱引用智能指针weak_ptr初始化和相关的操作函数 的相关文章

  • GetType() 在 Type 实例上返回什么?

    我在一些调试过程中遇到了这段代码 private bool HasBaseType Type type out Type baseType Type originalType type GetType baseType GetBaseTyp
  • ComboBox DataBinding 导致 ArgumentException

    我的几个类对象 class Person public string Name get set public string Sex get set public int Age get set public override string
  • 如何填充 ToolStripComboBox?

    我发现它很难将数据绑定到ToolStripComboBox 好像没有这个ValueMember and DisplayMember特性 怎么绑定呢 访问toolstripcombobox中包装的组合框并访问其ValueMember Disp
  • 查看 NuGet 包依赖关系层次结构

    有没有一种方法 文本或图形 来查看 NuGet 包之间的依赖关系层次结构 如果您使用的是新的 csproj 您可以在此处获取所有依赖项 在项目构建后 项目目录 obj project assets json
  • 从客户端访问 DomainService 中的自定义对象

    我正在使用域服务从 Silverlight 客户端的数据库中获取数据 在DomainService1 cs中 我添加了以下内容 EnableClientAccess public class Product public int produ
  • 将 Long 转换为 DateTime 从 C# 日期到 Java 日期

    我一直尝试用Java读取二进制文件 而二进制文件是用C 编写的 其中一些数据包含日期时间数据 当 DateTime 数据写入文件 以二进制形式 时 它使用DateTime ToBinary on C 为了读取 DateTime 数据 它将首
  • 为什么可以通过ref参数修改readonly字段?

    考虑 class Foo private readonly string value public Foo Bar ref value private void Bar ref string value value hello world
  • 启动时的 Excel 加载项

    我正在使用 Visual C 创建 Microsoft Excel 的加载项 当我第一次创建解决方案时 它包含一个名为 ThisAddIn Startup 的函数 我在这个函数中添加了以下代码 private void ThisAddIn
  • 打破 ReadFile() 阻塞 - 命名管道 (Windows API)

    为了简化 这是一种命名管道服务器正在等待命名管道客户端写入管道的情况 使用 WriteFile 阻塞的 Windows API 是 ReadFile 服务器已创建启用阻塞的同步管道 无重叠 I O 客户端已连接 现在服务器正在等待一些数据
  • 在视口中查找 WPF 控件

    Updated 这可能是一个简单或复杂的问题 但在 wpf 中 我有一个列表框 我用一个填充数据模板从列表中 有没有办法找出特定的数据模板项位于视口中 即我已滚动到其位置并且可以查看 目前我连接到了 listbox ScrollChange
  • 为什么我的单选按钮不起作用?

    我正在 Visual C 2005 中开发 MFC 对话框应用程序 我的单选按钮是 m Small m Medium 和 m Large 它们都没有在我的 m Summary 编辑框中显示应有的内容 可能出什么问题了 这是我的代码 Pizz
  • WPF DataGridTemplateColumn 组合框更新所有行

    我有这个 XAML 它从 ItemSource 是枚举的组合框中选择一个值 我使用的教程是 http www c sharpcorner com uploadfile dpatra combobox in datagrid in wpf h
  • 在屏幕上获取字符

    我浏览了 NCurses 函数列表 似乎找不到返回已打印在屏幕上的字符的函数 每个字符单元格中存储的字符是否有可访问的值 如果没有的话Windows终端有类似的功能吗 我想用它来替换屏幕上某个值的所有字符 例如 所有a s 具有不同的特征
  • WebBrowser.Print() 等待完成。 。网

    我在 VB NET 中使用 WebBrowser 控件并调用 Print 方法 我正在使用 PDF 打印机进行打印 当调用 Print 时 它不会立即启动 它会等到完成整个子或块的运行代码 我需要确保我正在打印的文件也完整并继续处理该文件
  • 实体框架中的“it”是什么

    如果以前有人问过这个问题 请原谅我 但我的任何搜索中都没有出现 它 我有两个数据库表 Person 和 Employee 对每个类型的表进行建模 例如 Employee is a Person 在我的 edmx 设计器中 我定义了一个实体
  • 在 Windows Phone silverlight 8.1 上接收 WNS 推送通知

    我有 Windows Phone 8 1 silverlight 应用程序 我想使用新框架 WNS 接收通知 我在 package appxmanifest 中有
  • 使用 omp_set_num_threads() 将线程数设置为 2,但 omp_get_num_threads() 返回 1

    我有以下使用 OpenMP 的 C C 代码 int nProcessors omp get max threads if argv 4 NULL printf argv 4 s n argv 4 nProcessors atoi argv
  • 如何减少具有多个单元的 PdfPTable 的内存消耗

    我正在使用 ITextSharp 创建一个 PDF 它由单个 PdfTable 组成 不幸的是 对于特定的数据集 由于创建了大量 PdfPCell 我遇到了内存不足异常 我已经分析了内存使用情况 我有近百万个单元格的 1 2 在这种情况下有
  • 如何使用 C++11 using 语法键入定义函数指针?

    我想写这个 typedef void FunctionPtr using using 我该怎么做呢 它具有类似的语法 只不过您从指针中删除了标识符 using FunctionPtr void 这是一个Example http ideone
  • OpenCV SIFT 描述符关键点半径

    我正在深入研究OpenCV的SIFT描述符提取的实现 https github com Itseez opencv blob master modules nonfree src sift cpp 我发现了一些令人费解的代码来获取兴趣点邻域

随机推荐

  • MatLab 隨機生成矩阵 复矩阵 单位下三角实矩阵 单位下三角复矩阵 矩阵求逆 矩阵乘法 matlab代码

    1 驗證 單位對角實矩陣的逆矩陣計算結果 2 驗證 單位對焦複矩陣的逆矩陣計算結果 n 7 real number field A rand n n L eye n for j 1 n L j 1 n j A j 1 n j end L L
  • ue4的UPROPERTY()

    继续学习B站的up主来自程序员的暴击的视频教程 我的理解就是属性 这个成员变量如何用 初步判断 只读和可读写 在myShowActor类里两个成员变量 UPROPERTY VisibleAnywhere Category Start int
  • 上海区块链会议演讲ppt_演讲和会议的软件开发人员指南

    上海区块链会议演讲ppt 软件开发会议提供了许多机会来促进您作为软件开发人员的职业发展 正如我们在网络一章中讨论的那样 参加会议可能是一个很好的网络机会 但是它们也是向该领域一些最高级程序员学习的好地方 但是 如果您真的想从软件开发会议中获
  • learn more study less:如何高效学习

    博主狂言 几句有用的话 两个序 前言 如何使用本书 整体性学习策略 learn more study less 什么是整体性学习 结构 模型 熟悉的结构成熟结构 高速公路 整体性学习的顺序 获取阶段 理解阶段 拓展阶段 纠错阶段 应用阶段
  • 适用于嵌入式单片机的差分升级通用库+详细教程

    文章目录 1 什么是差分 增量升级 2 差分升级实现原理 3 关键点一 差分包制作过程 4 关键点二 嵌入式设备中差分算法库的移植 还原差分包 4 1 移植开关算法库代码 4 2 使用该库的流程 4 2 1 使用库的接口 4 2 2 接口使
  • cvui.h 使用总结

    很多情况下个人更多用QT搭配opencv进行一系列开发 QT可以迅速开发出合乎要求的界面 但是实际上 试验过程中并不需要一个美观且功能齐全的界面 使用opencv进行图像处理 可能反反复复使用的是按键 勾选按钮 图片显示 参数修改或者显示等
  • rk3588 与 rk3399 差异比较

    rk3588 与 rk3399 差异比较 在2016年中 瑞芯微 Rockchip 在深圳会展中心召开首届VR生态链对接峰会 正式发布 VR 旗舰级产品 RK3399 在2021年底 瑞芯微 Rockchip 在福州第六届开发者大会 正式发
  • gradle wapper时异常(task with that name already exists)

    场景 新服务发布到测试环境打包失败 原因 1 种子项目配置了gradle版本 导入本地的时候选择使用项目的gradle Use default gradle wrapper recommended 2 直接在terminal里面输入 gra
  • IntelliJ IDEA 2017.3.1 使用手册

    因为CSDN博客时不时会报错 后续更新在 https my oschina net datadev blog 2876471 目录 1 激活 首次设置 2 创建maven项目 3 执行maven命令 4 创建maven moudle工程 5
  • mmyolo训练yolov5~ppyoloe

    使用mmyolo检测工具箱 完成yolo系列算法的训练 包括环境的搭建及yolo系列算法的配置文件等 mmyolo官方地址 https github com open mmlab mmdeploy 相关文档 https github com
  • 干货满满【JVM监控及诊断工具-GUI篇】

    JVM监控及诊断工具 GUI篇 3 1 工具概述 使用上一章命令行工具或组合能帮您获取目标Java应用性能相关的基础信息 但它们存在下列局限 1 无法获取方法级别的分析数据 如方法间的调用关系 各方法的调用次数和调用时间等 这对定位应用性能
  • Recylerview(list,九宫格,瀑布流布局)

    package com example recyclerview import android support v7 app AppCompatActivity import android os Bundle import android
  • Java中类和对象的关系

    一 基本概念 1 类 类是一个模板 它描述一类对象的行为和状态 比如一张汽车设计图纸 2 对象 对象表示现实世界中一个具体的事物 对象是类的一个实例 有状态和行为 例如 一条狗是一个对象 它的状态有 颜色 名字 品种 行为有 摇尾巴 叫 吃
  • 闲来无事搭个代理池子

    基于ProxyPool创建Proxifier代理 如题目所见 闲来无事在做测试时发现被某网站封了IP 为防止再被封掉 因此有了这篇文章和搭建过程 0x01 安装redis服务 ubuntu16 04 apt get install redi
  • FISCO BCOS(十五)——— Windows下的go环境配置及beego环境配置并解决bee run报错问题

    1 下载地址 https golang google cn dl 2 双击打开下载的文件 一路按照默认点击下一步 安装位置可选 默认安装在c盘 3 go环境配置 很重要的 在系统变量名中新建变量名 GOPATH 变量值 E go space
  • React 合成事件

    文章借鉴 pingan8787 React合成事件 和 React合成事件官方文档 React 合成事件 一 概念介绍 React合成事件是React 模拟原生DOM事件所有能力 的一个事件对象 根据 W3C规范 来定义合成事件 兼容所有浏
  • UE4大数据可视化教程(21)——大屏云渲染通用像素流解决方案

    目录 项目打包前操作 复制信令服务器文件 快捷打开信令服务和启动项目 替换项目
  • 虚拟机中的Windows重置系统密码

    概述 相信大家不管是在企业还是个人都或多或少接触过虚拟机 在安装操作系统的时候 有的需要密码 而且默认有时总是提示需要更改密码 导致忘记密码 但又不能重装操作系统也不能回退就很烦 这里本博主今天突然想到这个问题就出一篇文章 虽然我没有忘记过
  • 软件工程基础知识复习宝典

    前言 此文档为个人大学时期应付期末考试时自行总结 用于理解并背诵相应的基本概念 一些计算和画图之类的内容需要结合书本例题进行复习 多做习题深刻掌握 中间大标题为老师给出的考纲中建议每一章需要掌握的一些知识点 如若需要doc文档版打印复习 请
  • [C++11]弱引用智能指针weak_ptr初始化和相关的操作函数

    弱引用智能指针 std weak ptr 可以看做是 shared ptr 的助手 它不管理 shared ptr 内部的指针 std weak ptr 没有重载操作符 和 gt 因为它不共享指针 不能操作资源 所以它的构造不会增加引用计数