weak_ptr 是如何工作的?

2024-03-07

我明白如何使用weak_ptr and shared_ptr。我明白如何shared_ptr通过计算其对象中的引用数量来工作。如何weak_ptr工作?我尝试阅读 boost 源代码,但我对 boost 还不够熟悉,无法理解它使用的所有内容。

Thanks.


shared_ptr使用额外的“计数器”对象(又名“共享计数”或“控制块”)来存储引用计数。 (顺便说一句:那个“计数器”对象还存储删除器。)

Every shared_ptr and weak_ptr包含一个指向实际指针的指针,以及另一个指向“计数器”对象的指针。

实施weak_ptr,“counter”对象存储两个不同的计数器:

  • “使用次数”是指使用次数shared_ptr指向该对象的实例。
  • “弱计数”是指weak_ptr指向该对象的实例,如果“使用计数”仍然 > 0,则加一。

当“使用计数”达到零时,指针被删除。

当“弱计数”达到零时,“计数器”辅助对象将被删除(这意味着“使用计数”也必须为零,见上文)。

当你试图获得一个shared_ptr from a weak_ptr,库自动检查“使用计数”,如果它 > 0,则递增它。如果成功的话你会得到你的shared_ptr。如果“使用计数”已经为零,您会得到一个空的shared_ptr实例代替。


EDIT:现在,为什么当两个计数都降至零时,他们要向弱计数加一,而不是仅仅释放“计数器”对象?好问题。

另一种方法是当“使用计数”和“弱计数”都降至零时删除“计数器”对象。第一个原因是:在每个平台上原子地检查两个(指针大小的)计数器是不可能的,即使在平台上,它也比仅检查一个计数器更复杂。

另一个原因是删除器必须保持有效直到执行完毕。由于删除器存储在“计数器”对象中,这意味着“计数器”对象必须保持有效。考虑一下如果有一个会发生什么shared_ptr和一个weak_ptr到某个对象,并且它们在并发线程中同时重置。让我们说shared_ptr首先。它将“使用计数”减少到零,并开始执行删除器。现在weak_ptr将“弱计数”减少到零,并发现“使用计数”也为零。因此它删除了“计数器”对象以及删除器。当删除器仍在运行时。

当然,可以采用不同的方法来确保“计数器”对象保持活动状态,但我认为将“弱计数”增加一是一种非常优雅且直观的解决方案。 “弱计数”成为“计数器”对象的引用计数。自从shared_ptrs 也引用计数器对象,它们也必须增加“弱计数”。

一个可能更直观的解决方案是增加每个单独的“弱计数”shared_ptr,因为每一个shared_ptrhold 是对“计数器”对象的引用。

为所有人添加一个shared_ptr实例只是一种优化(在复制/分配时保存一个原子增量/减量shared_ptr实例)。

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

weak_ptr 是如何工作的? 的相关文章

  • 如何从该 Voronoi 图数据中获取单元格字典?

    使用找到的voronoi delaunay图生成库在这个节目中 http sourceforge net projects mapmanager 这是基于 财富 最初的实施他的算法 http en wikipedia org wiki Fo
  • VSTS 构建失败/发布无法在 bin 文件夹中找到 roslyn\csc.exe

    我们有一个网站项目 安装了以下 nuget 软件包 Microsoft CodeDom Providers DotNetCompilerPlatform 1 0 8 Microsoft Net Compilers 2 4 0 The web
  • 同步执行异步函数

    我对此主题进行了大量搜索 并且阅读了本网站上有关此主题的大部分帖子 但是我仍然感到困惑 我需要一个直接的答案 这是我的情况 我有一个已建立的 Winform 应用程序 但无法使其全部 异步 我现在被迫使用一个全部编写为异步函数的外部库 在我
  • C++ 非类型参数包扩展

    我正在编写由单一类型参数化的模板函数 并且具有可变数量的相同类型 而不是不同类型 的参数 它应该检查第一个值是否在其余值中 我想这样写 include
  • Entity Framework 4.1 RC:Code First EntityTypeConfiguration 继承问题

    我尝试使用通用的 EntityTypeConfiguration 类来配置所有实体的主键 以便每个派生的配置类不会重复自身 我的所有实体都实现一个公共接口 IEntity 它表示每个实体必须有一个 int 类型的 Id 属性 我的配置基类如
  • C++ 私有静态成员变量

    此 C 代码在编译时产生链接器错误 A h class A public static void f private static std vector
  • 如何在 C++ 中对静态缓冲区执行字符串格式化?

    我正在处理一段对性能要求非常高的代码 我需要执行一些格式化的字符串操作 但我试图避免内存分配 甚至是内部库的内存分配 在过去 我会做类似以下的事情 假设是 C 11 constexpr int BUFFER SIZE 200 char bu
  • C 中“for”循环中的两个变量

    我正在编写一些代码 需要在其中使用两个变量for环形 下面的代码看起来没问题吗 它确实给了我预期的结果 for loop 1 offset loop 2 offset 2 loop 1 gt offset 190 loop 2 lt 190
  • 枚举器上的 [[maybe_unused]]

    查看规格 maybe unused http en cppreference com w cpp language attributes 它指出 出现在类 typedef 变量 非静态数据成员 函数 枚举或枚举器的声明中 如果编译器对未使用
  • 简单的文档管理系统和API [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 无法将方法组“Read”转换为非委托类型“bool”

    我正在尝试使用SqlDataReader检查条目是否存在 如果存在则返回ID 否则返回false 当我尝试编译时 出现错误 无法将方法组 Read 转换为非委托类型 bool 我一直在遵循在 VB 中找到的示例 但似乎翻译可能不正确 pri
  • 如何使用 libpq 获取双精度值?

    The examples http www postgresql org docs 9 3 interactive libpq example htmllibpq 文档中展示了如何通过将整数值转换为主机字节序表示来获取整数值 我很好奇必须做
  • 如何从代码隐藏中向我的 div 添加点击事件?

    如何从代码隐藏中向我的 div 添加点击事件 当我点击 div 时 会出现一个消息框 其中显示 您想删除它吗 并在框中显示 是 或 否 全部来自后面的代码 while reader Read System Web UI HtmlContro
  • 如何解释“错误C2018:未知字符'0x40'?[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 在编译一些代码时 我收到以下信息 错误 C2018 未知字符 0x40 我想知道如何解决这样的问题 这是我要开始的地方
  • 我应该使用多个 HttpClient 来进行批量异步 GET 请求吗?

    我有一个场景 我需要在尽可能短的时间内发出大量 GET 请求 想想大约 1000 个 我知道通常最好保留一个客户端并尽可能重用它 Create Single HTTP Client HttpClient client new HttpCli
  • 使用 roslyn 扩展 C# 语法

    我试图在没有 else 情况的情况下实现 return if return value if 因为我只想在条件有效时返回或返回一个值 我知道 有if condition return or if condition return value
  • 如何将 Metro 应用部署到桌面?

    我正在尝试将我的 C 应用程序部署到我的 Windows 8 Metro 桌面 我可以在 bin 文件夹中看到部署的文件 但是当我尝试打开它们时 出现以下错误 该应用程序只能在 AppContainer 的上下文中运行 我检查了属性上下文菜
  • C/C++ 通过 Android NDK 在 JNI 中看不到 Java 方法

    我正在尝试从使用 NDK 构建的 C 类文件调用 Java 方法 它不断抛出常见的 未找到非静态方法 错误并导致整个 Android 应用程序崩溃 下面的代码片段 有些东西可能不需要 但我按原样保留它们 因为焦点 问题在于refreshJN
  • 具有多种类型的 C# 泛型类型推断

    我有以下通用方法 用于将一种类型的输入对象序列化为超类型 如下所示 public string SerialiseAs
  • 如何将 char 转换为 unsigned int?

    我有一个字符数组 它实际上用作字节数组 而不是用于存储文本 在数组中 有两个特定字节表示我需要存储到无符号 int 值中的数值 下面的代码解释了设置 char bytes bytes 2 bytes 0 0x0C For the sake

随机推荐

  • 有没有办法在 return 语句之后做更多的工作?

    我有点好奇返回结果后是否可以在函数中做更多的工作 基本上 我正在使用金字塔框架 只是用 python 编码 创建一个网站 在处理输入后 我返回变量来渲染页面 但有时我想在渲染页面后做更多工作 例如 您访问我的网站并更新您的个人资料 您所关心
  • BigQuery 数据集通配符?

    我用过tableBigQuery 中的通配符功能 但是否可以使用通配符跨多个查询datasets在一个项目内 不 目前这是不可能的 技术原因之一是 如果表通配符跨越数据集 查找涉及的表会更加困难
  • html文本框形式不允许输入

    html 表单中是否有任何类不允许您在该文本框中输入或更改值 但你可以看到它的内容 例如下面的代码将允许你看到mysql数据库中记录的内容 但我想要的是它不被编辑 我将在下面的代码中添加什么 以便用户不会编辑其内容 tr td font s
  • 使用 ListAdapter 填充 ScrollView 布局内的 LinearLayout

    我面临一个非常常见的问题 我布置了一个活动 现在发现它应该显示其中的一些项目ScrollView 通常的方法是使用现有的ListAdapter 将其连接到ListView and BOOM我会有我的物品清单 BUT你不应该放置一个嵌套的Li
  • 如何在 Eclipse 中指定预处理器指令?

    Eclipse 中如何为不同的配置指定预处理器指令 例如 如果我有多个电源 应该以不同的配置运行并指定 ifdef Problem1 main func endif Problem1 请注意 这是托管 makefile 的情况 The 文档
  • 同位素 v2 网格 - 多个过滤器 - 隐藏空过滤器

    我当前的同位素网格有两个下拉过滤器 用于对网格项目进行排序 第一个过滤器是菜单类型 第二个过滤器是饮料类型 然而 每种菜单类型并不包含所有饮料类型 因此当选择某些过滤器配置时 不会显示任何结果 这是正确的 但我想通过当用户选择第一个过滤器时
  • jquery 不从 javascript 函数调用 Web 方法

    长期从事 WinForm 程序员 但对 Web 编程领域还是个新手 我有 Visual Studio 2010 并且创建了一个新的网站项目 我似乎无法让 ajax 调用我创建的 webmethod 当我单击页面上的按钮时 什么也没有发生 当
  • 使用 Anaconda 设置 Hydrogen 和 Atom 管理 python 安装

    我已将我的 python 3 可执行文件添加到系统路径 违背 Anaconda 的建议 以尝试让 Hydrogen 以及实际上任何 Atom 扩展 插件 在 Atom 中运行代码行或代码块 脚本 原子插件似乎可以工作 我选择一些代码并输入c
  • npm 错误!致命:无法找到“https”的远程帮助程序

    我在跑npm install在远程会话的 React Native 项目中 更具体地说 这npm install是我运行的构建脚本的一部分VSTS代理 https github com microsoft vsts agent 我遇到了这个
  • 在mockito中模拟通用scala方法

    我正在开发一个 Scala 项目 使用 Mockito 作为模拟框架 我想模拟以下通用 Scala 方法 def parseXml T ClassTag xmlUrl URL xsdUrl Option URL Option T 当嘲笑时
  • 用于将十六进制字符串转换为字节数组的预处理器宏

    我已将 AES 128 密钥定义为 IDE 中的构建符号 以便它像这样调用 GCC arm none eabi gcc D AES KEY 3B7116E69E222295163FF1CAA1681FAC 这相当于 define AES K
  • 如何在 html 内使用双百分号(%%variable%%)括起来的 PHP 变量

    我正在修改发送到电子邮件的 html 文件 我需要通过以下方式创建一些检查PHP到变量但是我不知道双倍百分比是多少 我尝试在网上搜索 但我看到的结果甚至与编程无关 我需要确定何时发送另一封邮件 因为我只能在 30 分钟后发送邮件时才能看到输
  • 如何快速更新锚点约束

    我想在 iOS 中创建一个像 android 一样的菜单 我在用着布局限制建立限制条件 当我尝试更新左侧时 我遇到了这个问题约束单击按钮时的图像 它应该动画到单击按钮的位置 谁能帮我 它应该支持横向和纵向 我不想使用第三方代码 也不想使用N
  • log4net 日志正在创建但仍为空

    我正在尝试使用log4net http logging apache org log4net 当我启动应用程序时 它会创建日志文件 但无论我调用多少次Log Info Application Started 它仍然是空的 我研究了谷歌返回的
  • AWS IOT 连接在 IPAD OS v12.1.1 上关闭

    当我们在 ios 版本 12 1 1 上使用 wss 协议连接到 AWS IoT 时 我们能够成功连接到 IoT 但立即我们可以看到 IoT 触发 onError 事件 然后连接关闭 它尝试再次重新连接 但没有任何运气 我们从 IoT 得到
  • Ruby 中的舍入不一致?

    Ruby 的舍入有错误吗 为什么它的行为是这样的 gt gt 1 14 1 15 1 16 map x 1f x gt 1 1 1 1 1 2 gt gt 1 4 1 5 1 6 map x 0f x gt 1 2 2 例如 为什么 1 1
  • 使用 vcpkg 编译 gRPC C++ 示例

    我正在尝试使用与 vcpkg 管理器一起安装的 grpc 来构建和运行 grpc 示例 我通过克隆并查找 grpc 安装了 vcpkg 管理器 如下所示 sudo apt get install y unzip build essentia
  • eclipse appcompat->res->drawable-xxxhdpi 错误

    我刚刚将我的日食更新为SDK 21 我知道每次我创建项目时 Eclipse 也会创建名为appcompat v7 但是appcompat v7显示错误在res drawable xxxhdpi文件夹 这也使我的项目出错 并在控制台显示此警报
  • pip install mod_wsgi,如何设置MOD_WSGI_APACHE_ROOTDIR环境?

    我正在尝试在 Windows 10 中安装 mod wsgi 命令pip install mod wsgi给我错误 RuntimeError No Apache installation can be found Set the MOD W
  • weak_ptr 是如何工作的?

    我明白如何使用weak ptr and shared ptr 我明白如何shared ptr通过计算其对象中的引用数量来工作 如何weak ptr工作 我尝试阅读 boost 源代码 但我对 boost 还不够熟悉 无法理解它使用的所有内容