gpt4 book ai didi

c++ - weak_ptr 是如何工作的?

转载 作者:IT老高 更新时间:2023-10-28 13:23:14 28 4
gpt4 key购买 nike

我了解如何使用 weak_ptrshared_ptr。通过计算对象中的引用数,我了解 shared_ptr 的工作原理。 weak_ptr 是如何工作的?我尝试通读 boost 源代码,但我对 boost 不够熟悉,无法理解它使用的所有东西。

谢谢。

最佳答案

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

每个 shared_ptrweak_ptr 都包含一个指向实际指针对象的指针,以及一个指向“计数器”对象的第二个指针。

为了实现weak_ptr,“计数器”对象存储了两个不同的计数器:

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

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

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

当您尝试从 weak_ptr 获取 shared_ptr 时,库会自动检查“使用计数”,如果它 > 0,则将其递增。如果成功,您将获得 shared_ptr。如果“使用计数”已经为零,您将获得一个空的 shared_ptr 实例。


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

当“使用计数”和“弱计数”都降为零时,替代方法是删除“计数器”对象。这是第一个原因:并非在每个平台上都可以原子地检查两个(指针大小的)计数器,即使在哪里,也比只检查一个计数器更复杂。

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

当然会有不同的方法来确保“计数器”对象保持事件状态,但我认为将“弱计数”增加一个是一种非常优雅和直观的解决方案。 “弱计数”成为“计数器”对象的引用计数。而且由于 shared_ptr 也引用了计数器对象,因此它们也必须增加“弱计数”。

一个可能更直观的解决方案是增加每个 shared_ptr 的“弱计数”,因为每个 shared_ptr 都持有对“计数器”对象的引用.

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

关于c++ - weak_ptr 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5671241/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com