gpt4 book ai didi

c++ - 为什么 shared_ptr 需要保存 weak_ptr 的引用计数?

转载 作者:可可西里 更新时间:2023-11-01 18:04:50 25 4
gpt4 key购买 nike

引自 C++ Primer $12.1.6:

A weak_ptr (Table 12.5) is a smart pointer that does not control the lifetime of the object to which it points. Instead, a weak_ptr points to an object that is managed by a shared_ptr. Binding a weak_ptr to a shared_ptr does not change the reference count of that shared_ptr. Once the last shared_ptr pointing to the object goes away, the object itself will be deleted. That object will be deleted even if there are weak_ptrs pointing to it—hence the name weak_ptr, which captures the idea that a weak_ptr shares its object “weakly.”

但是,我读过一个article说:

using make_shared is more efficient. The shared_ptr implementation has to maintain housekeeping information in a control block shared by all shared_ptrs and weak_ptrs referring to a given object. In particular, that housekeeping information has to include not just one but two reference counts:

  1. A “strong reference” count to track the number of shared_ptrs currently keeping the object alive. The shared object is destroyed (and possibly deallocated) when the last strong reference goes away.

  2. A “weak reference” count to track the number of weak_ptrs currently observing the object. The shared housekeeping control block is destroyed and deallocated (and the shared object is deallocated if it was not already) when the last weak reference goes away.

据我所知,make_shared创建的shared_ptr在同一个control block中。与那些 ref countings.So 对象将不会被释放,直到最后一个 weak_ptr 过期。

问题:

  1. Primer 错了吗? 因为 weak_ptr 实际上会影响该对象的生命周期。
  2. 为什么 shared_ptr 需要跟踪它的弱引用?weak_ptr 可以通过检查控制 block 中的 strong refs 来判断对象是否存在,所以我认为控制 block 不需要跟踪弱引用
  3. 出于好奇,shared_ptr 创建的控制 block 是什么样子的?是不是像这样:

    template<typename T>
    class control_block
    {
    T object;
    size_t strong_refs;
    size_t weak_refs;
    void incre();
    void decre();
    //other member functions...
    };
    //And in shared_ptr:
    template<typename T>
    class shared_ptr
    {
    control_block<T> block;//Is it like this?So that the object and refs are in the same block?
    //member functions...
    };

最佳答案

引用计数控制指向对象的生命周期。弱计数不会,但确实控制(或参与控制)控制 block 的生命周期。

如果引用计数变为 0,则对象被销毁,但不一定释放。当弱计数变为 0(或者当引用计数变为 0,如果在这种情况下没有 weak_ptr),控制 block 被销毁和释放,并且对象的存储被释放(如果它还没有的话)。

destroyingdeallocating pointed-to-object 之间的分离是一个你不需要关心的实现细节,但它是由使用 make_shared.

如果你这样做

shared_ptr<int> myPtr(new int{10});

您为 int 分配存储空间,然后将其传递给 shared_ptr 构造函数,该构造函数分别为控制 block 分配存储空间。在这种情况下,int 的存储可以尽早释放:一旦引用计数达到 0,即使仍然存在弱计数。

如果你这样做

auto myPtr = make_shared<int>(10);

然后 make_shared 可能会执行优化,它一次性为 int 和控制 block 分配存储空间。这意味着在控制 block 的存储也可以被释放之前,int 的存储不能被释放。当引用计数达到 0 时,int 的生命周期结束,但直到弱计数达到 0 时,它的存储才会被释放。

现在清楚了吗?

关于c++ - 为什么 shared_ptr 需要保存 weak_ptr 的引用计数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49585818/

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