【C++11智能指针】weak_ptr概述、创建、常用操作、尺寸

2023-11-03

1.weak_ptr概述

weak_ptr 是一种不控制所指向对象生存期的智能指针,它指向由一个 shared_ptr 管理的对象。

将一个 weak_ptr 绑定到一个 shared_ptr 不会改变 shared_ptr 的引用计数,更确切地说,weak_ptr 的构造和析构不会增加或减少所指向对象的引用计数。

一旦最后一个指向对象的 shared_ptr 被销毁,对象就会被释放,即使有 weak_ptr 指向对象,对象也还是会被释放,因此,weak_ptr 的名字抓住了这种智能指针“弱”共享对象的特点。

weak_ptr 不是一种独立的智能指针,不能用来操作所指向的资源,所以它看起来像是 shared_ptr 的助手。weak_ptr 能够监视到它所指向的对象是否存在。

2.weak_ptr的创建

当我们创建一个 weak_ptr 时,要用一个 shared_ptr 来初始化它:

#include <iostream>
using namespace std;

int main()
{
	auto sp = make_shared<int>(100); // 强引用计数从0变1
	
	weak_ptr<int> wp(sp); // wp弱共享sp,强引用计数仍为1,弱引用计数从0变1

	return 0;
}

强引用计数才能决定对象的生存期,弱引用计数对对象的生存期没有影响。

2.1 lock()

由于对象可能不存在,我们不能使用 weak_ptr 直接访问对象,而必须调用 lock() 函数。

lock() 的功能就是检查 weak_ptr 所指向的对象是否存在,如果存在,则返回一个指向该对象的 shared_ptr,同时指向该对象的强引用计数就会加 1 1 1;如果不存在,则返回一个空的 shared_ptr。

#include <iostream>
using namespace std;

int main()
{
	auto sp = make_shared<int>(100); // 强引用计数从0变1
	
	weak_ptr<int> wp(sp); // wp弱共享sp,强引用计数仍为1,弱引用计数从0变1

	auto sp2 = wp.lock(); // 强引用计数从1变2,弱引用计数仍为1

	if (sp2)
	{
		cout << "wp所指向的对象存在" << endl;
		*sp2 = 200;
	}
	else
	{
		cout << "wp所指向的对象不存在" << endl;
	}

	return 0;
}

3.weak_ptr的常用操作

在这里插入图片描述

3.1 use_count()

w.use_count():返回与 w 共享对象的 shared_ptr 的数量。

#include <iostream>
using namespace std;

int main()
{
	auto sp1 = make_shared<int>(100);

	auto sp2(sp1);

	weak_ptr<int> wp(sp1);

	cout << wp.use_count() << endl; // 2

	return 0;
}

3.2 expired()

w.expired():判断是否过期。若 w.use_count() 0 0 0,表示该弱指针所指向的对象已经不存在了,则返回 true,否则返回 false。

#include <iostream>
using namespace std;

int main()
{
	auto sp = make_shared<int>(100);

	weak_ptr<int> wp(sp);

	cout << wp.use_count() << endl; // 1

	sp.reset();

	cout << wp.use_count() << endl; // 0

	if (wp.expired()) cout << "所指对象已经过期" << endl;
	else cout << "所指对象没有过期" << endl;

	return 0;
}

3.3 reset()

w.reset():将该弱引用指针设置为空,不影响指向该对象的强引用数量,但指向该对象的弱引用数量会减少 1 1 1

#include <iostream>
using namespace std;

int main()
{
	auto sp1 = make_shared<int>(100); // 强引用计数从0变1

	auto sp2(sp1); // 强引用计数从1变2

	weak_ptr<int> wp(sp1); // 强引用计数仍为2,弱引用计数从0变1

	cout << wp.use_count() << endl; // 2

	wp.reset(); // 强引用计数仍为2,弱引用计数从1变0

	cout << sp1.use_count() << endl; // 2

	return 0;
}

4.weak_ptr的尺寸

weak_ptr 的尺寸和 shared_ptr 的尺寸一样大,都是裸指针的 2 倍。

#include <iostream>
using namespace std;

int main()
{
	int* p;

	cout << sizeof(p) << endl; // x86:4,x64:8

	weak_ptr<int> wp;

	cout << sizeof(wp) << endl; // x86:8,x64:16

	return 0;
}

在这里插入图片描述

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

【C++11智能指针】weak_ptr概述、创建、常用操作、尺寸 的相关文章

  • 编译时运算符

    有人可以列出 C 中可用的所有编译时运算符吗 C 中有两个运算符 无论操作数如何 它们的结果始终可以在编译时确定 它们是sizeof 1 and 2 当然 其他运算符的许多特殊用途可以在编译时解决 例如标准中列出的那些整数常量表达式 1 与
  • 如何使用 C# 中的参数将用户重定向到 paypal

    如果我有像下面这样的简单表格 我可以用它来将用户重定向到 PayPal 以完成付款
  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre
  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • 将 VSIX 功能添加到 C# 类库

    我有一个现有的单文件生成器 位于 C 类库中 如何将 VSIX 项目级功能添加到此项目 最终目标是编译我的类库项目并获得 VSIX 我实际上是在回答我自己的问题 这与Visual Studio 2017 中的单文件生成器更改 https s
  • C# 中通过 Process.Kill() 终止的进程的退出代码

    如果在我的 C 应用程序中 我正在创建一个可以正常终止或开始行为异常的子进程 在这种情况下 我通过调用 Process Kill 来终止它 但是 我想知道该进程是否已退出通常情况下 我知道我可以获得终止进程的错误代码 但是正常的退出代码是什
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 链接器错误:已定义

    我尝试在 Microsoft Visual Studio 2012 中编译我的 Visual C 项目 使用 MFC 但出现以下错误 error LNK2005 void cdecl operator new unsigned int 2
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • C++ 中类级 new 删除运算符的线程安全

    我在我的一门课程中重新实现了新 删除运算符 现在我正在使我的代码成为多线程 并想了解这些运算符是否也需要线程安全 我在某处读到 Visual Studio 中默认的 new delete 运算符是线程安全的 但这对于我的类的自定义 new
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低

随机推荐

  • IT伦理与道德

    1 个人隐私问题 个人隐私包括传统的个人隐私和现代个人数据 传统的个人隐私有姓名 出生年月 身份证编号 婚姻家庭 教育等 现代个人数据有用户名和密码 IP地址等 合理合法的隐私应受到保护 在计算机时代 隐私极易受到侵害 这最直接的影响就是公
  • LVS负载均衡服务器搭建

    LVS简介 现在LVS已经是Linux标准内核的一部分 在Linux2 4内核以前 使用LVS时必须重新编译内核以支持LVS功能模块 但是从Linux2 4内核心之后 已经完全内置了LVS的各个功能模块 无需给内核打任何补丁 可以直接使用L
  • 异步复位信号的 recovery和removal

    简而言之 DFF的复位置位信号不要在clk的跳变沿附近变化 而是要远离clk沿 一般逻辑对此时序不用关心 比如很多模块的操作流程是复位完了 才开启模块时钟 再启动模块工作 这种流程可以保证不会出现recovery和removal的问题 因为
  • IO流总结

    1 什么是IO I Input O Output 通过IO可以完成硬盘文件的读和写 Java中所有的流都在java io 下 2 IO流的分类 有多种分类方式 输入流 输出流 字节流 字符流 1 一种方式是按照流的方向进行分类 以内存作为参
  • 【C++】空间配置器

    目录 一 空间配置器概念 二 为什么需要空间配置器 三 SGI STL空间配置器实现原理 3 1 一级空间配置器 3 2 二级空间配置器 3 2 1 内存池 3 2 2 SGI STL中二级空间配置器设计 3 2 3 SGI STL二级空间
  • spyder的使用(python编辑器)

    spyder是Anaconda种自带的一种python编辑器 这个编辑器里面保存的是py文件 spyder 创建工程 运行 1 运行整个脚本文件 2 运行当前代码块 3 运行当前代码块 并跳至下一个 4 运行当前命令行 或选中的命令行 5
  • 通过Function Score Query优化Elasticsearch搜索结果

    在使用Elasticsearch进行全文搜索时 搜索结果默认会以文档的相关度进行排序 如果想要改变默认的排序规则 也可以通过sort指定一个或多个排序字段 但是使用sort排序过于绝对 它会直接忽略掉文档本身的相关度 根本不会去计算 在很多
  • 面试笔记(六)---Js实现eventHandler

    js事件的监听器的使用 1 当同一个对象使用 onclick的写法触发多个方法的时候 后一个方法会把前一个方法覆盖掉 也就是说 在对象的onclick事件发生时 只会执行最后绑定的方法 而用事件监听则不会有覆盖的现象 每个绑定的事件都会被执
  • 【算法与数据结构】669、LeetCode修剪二叉搜索树

    文章目录 一 题目 二 解法 三 完整代码 所有的LeetCode题解索引 可以看这篇文章 算法和数据结构 LeetCode题解 一 题目 二 解法 思路分析 450 LeetCode删除二叉搜索树中的节点两道题的思路几乎是一样的 只不过终
  • 常用数据清洗方法

    常用的数据清洗方法有 缺失值处理 包括删除包含缺失值的行或列 用均值 中位数或众数来填充缺失值 异常值处理 包括删除异常值或使用其他方法进行修正 数据规约 包括去重 合并重复数据 转换数据格式等 文本数据处理 包括去除停用词 词干提取 分词
  • OpenLayers隐藏默认放大放小按钮

    div div import Map View from ol import TileWMS from ol source TileWMS import TileLayer from ol layer Tile import ScaleLi
  • 深度选择器/deep/,关于elementui样式修改不了的问题完美解决

    深度选择器 deep 在vue elementui写项目时 时常elementui的效果不理想 但是又没办法直接修改elementui的样式 因为我们无法通过普通的选择器获取到我们要更改的标签 elementui自己加了一层 通常的解决办法
  • git 导出指定文件的所有commits

    多个补丁一个文件 git format patch 提交个数 stdout drivers staging wlags49 h2 gt wlags49 patches all patch 每一个补丁一个文件 git format patch
  • 十大常用算法之马踏棋盘算法

    十大常用算法的完整实现 一 二分查找算法 https blog csdn net weixin 46635575 article details 121532149 二 分治算法 https blog csdn net weixin 466
  • [自用代码]基于python的遥感影像传统分割方法(直方图双峰法,阈值分割法,模糊C均值法,超像素分割法,K-means,snake)

    文章目录 待分割图片 直方图双峰阈值分割法 代码 分割结果 阈值分割法 代码 分割结果 模糊C均值 代码 分割结果 超像素分割 代码 分割结果 K means 分割结果 主动轮廓模型 snake代码 利用canny提取图片边缘 对图片进行闭
  • python随机矩阵生成_python生成随机数和随机矩阵

    生成随机数 使用 random 模块 random random 用于随机生成一个0到1的浮点数 random randint start stop 随机生成 start stop 区间内的整数 代码示例 import random pri
  • 分析容器系统调用:Sysdig

    Sysdig is an open source cross platform powerful and flexible system monitoring and troubleshooting tool for Linux it al
  • zookeeper的基础概念

    目录 1 并发环境下面临的挑战 2 Zookeeper的介绍 3 zookeeper的理论 1 并发环境下面临的挑战 回忆我们学多线程的时候 网上有个图也是十分的有意思 其实我们把线程换成进程 相当于每台服务上跑了一个程序 相同的应用程序运
  • node node-sass sass-loader 版本对应问题

    node版本 16 18 1 1 卸载node sass npm uninstall node sass 2 安装node sass 当前本地node版本 16 18 1 npm i node sass 6 0 1 sass loader
  • 【C++11智能指针】weak_ptr概述、创建、常用操作、尺寸

    文章目录 1 weak ptr概述 2 weak ptr的创建 2 1 lock 3 weak ptr的常用操作 3 1 use count 3 2 expired 3 3 reset 4 weak ptr的尺寸 1 weak ptr概述