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 是如何工作的? 的相关文章

  • 属性对象什么时候创建?

    由于属性实际上只是附加到程序集的元数据 这是否意味着属性对象仅根据请求创建 例如当您调用 GetCustomAttributes 时 或者它们是在创建对象时创建的 或者 前两个的组合 在由于 CLR 的属性扫描而创建对象时创建 从 CLR
  • Signalr 在生产服务器中总是陷入长轮询

    当我在服务器中托管应用程序时 它会检查服务器端事件并始终回退到长轮询 服务器托管环境为Windows Server 2012 R1和IIS 7 5 无论如何 我们是否可以解决这个问题 https cloud githubuserconten
  • Func 方法参数的首选命名约定是什么?

    我承认这个问题是主观的 但我对社区的观点感兴趣 我有一个缓存类 它采用类型的缓存加载器函数Func
  • 模板类的不明确多重继承

    我有一个真实的情况 可以总结为以下示例 template lt typename ListenerType gt struct Notifier void add listener ListenerType struct TimeListe
  • 如何在没有 Control.Invoke() 的情况下从后台线程修改控件属性

    最近 我们遇到了一些旧版 WinForms 应用程序 我们需要更新一些新功能 在专家测试该应用程序时 发现一些旧功能被破坏 无效的跨线程操作 现在 在您认为我是新手之前 我确实有一些 Windows 窗体应用程序的经验 我不是专家 但我认为
  • FFMPEG Seeking 带来音频伪影

    我正在使用 ffmpeg 实现音频解码器 在读取音频甚至搜索已经可以工作时 我无法找到一种在搜索后清除缓冲区的方法 因此当应用程序在搜索后立即开始读取音频时 我没有任何工件 avcodec flush buffers似乎对内部缓冲区没有任何
  • 使用 Microsoft Graph API 订阅 Outlook 推送通知时出现 400 错误请求错误

    我正在尝试使用 Microsoft Graph API 创建订阅以通过推送通知获取 Outlook 电子邮件 mentions 我在用本文档 https learn microsoft com en us graph api subscri
  • 为什么禁止在 constexpr 函数中使用 goto?

    C 14 对你能做什么和不能做什么有规则constexpr功能 其中一些 没有asm 没有静态变量 看起来相当合理 但标准也不允许goto in constexpr功能 即使它允许其他控制流机制 这种区别背后的原因是什么 我以为我们已经过去
  • 如何针对 Nancy 中的 Active Directory 进行身份验证?

    这是一篇过时的文章 但是http msdn microsoft com en us library ff650308 aspx paght000026 step3 http msdn microsoft com en us library
  • C# 用数组封送结构体

    假设我有一个类似于 public struct MyStruct public float a 我想用一些自定义数组大小实例化一个这样的结构 在本例中假设为 2 然后我将其封送到字节数组中 MyStruct s new MyStruct s
  • 如何在 Team Foundation 上强制发表有意义的签入评论?

    我有一个开发团队有一个坏习惯 他们写道poor签入评论 当我们必须在团队基础上查看文件的历史记录时 这使得它成为一场噩梦 我已经启用了变更集评论政策 这样他们甚至可以在签到时留下评论 否则他们不会 我们就团队的工作质量进行了一些讨论 他们很
  • 使用 LINQ 查找列表中特定类型的第一个元素

    使用 LINQ 和 C 在元素列表中查找特定类型的第一个项目的最短表示法是什么 var first yourCollection OfType
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • 在 URL 中发送之前对特殊字符进行百分比编码

    我需要传递特殊字符 如 等 Facebook Twitter 和此类社交网站的 URL 为此 我将这些字符替换为 URL 转义码 return valToEncode Replace 21 Replace 23 Replace 24 Rep
  • 作为字符串的动态属性名称

    使用 DocumentDB 创建新文档时 我想设置属性名称动态地 目前我设置SomeProperty 像这样 await client CreateDocumentAsync dbs db colls x new SomeProperty
  • char指针或char变量的默认值是什么[重复]

    这个问题在这里已经有答案了 下面是我尝试打印 char 变量和指针的默认值 值的代码 但无法在控制台上看到它 它是否有默认值或只是无法读取 ASCII 范围 include
  • Bing 地图运行时错误 Windows 8.1

    当我运行带有 Bing Map 集成的 Windows 8 1 应用程序时 出现以下错误 Windows UI Xaml Markup XamlParseException 类型的异常 发生在 DistanceApp exe 中 但未在用户
  • C++ 成员函数中的“if (!this)”有多糟糕?

    如果我遇到旧代码if this return 在应用程序中 这种风险有多严重 它是一个危险的定时炸弹 需要立即在应用程序范围内进行搜索和销毁工作 还是更像是一种可以悄悄留在原处的代码气味 我不打算writing当然 执行此操作的代码 相反
  • 不同类型的指针可以互相分配吗?

    考虑到 T1 p1 T2 p2 我们可以将 p1 分配给 p2 或反之亦然吗 如果是这样 是否可以不使用强制转换来完成 或者我们必须使用强制转换 首先 让我们考虑不进行强制转换的分配 C 2018 6 5 16 1 1 列出了简单赋值的约束

随机推荐

  • 有没有办法在 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 还不够熟悉 无法理解它使用的所有内容