具有引用计数的共享智能指针实现

Shared Smart Pointer Implementation with Reference Counting

本文关键字:共享 智能 指针 实现 引用      更新时间:2023-10-16

在研究引用计数智能指针的一些实现时,我发现了这种类型的实现。

template<typename Type> 
class SmartRefCountPointer{
    Type* obj;
    size_t* count;  // <<--- Why pointer/ why is count on heap
}

你能解释一下为什么这个计数器被移到堆上而不是堆上吗?如果你能提供任何失败的案例,我将不胜感激。

计数器必须与指向同一对象的SmartRefCountPointer的其他实例共享。

引用计数指针的全部意义在于,有一个地方可以跟踪有多少引用。因此,这个位置必须是一个全局变量,或者是堆上的一个位置。您所显示的实现已为以后的选择。

指向同一对象的所有SmartRefCountPointer也应该更新同一计数器。这就是为什么您不能将计数器保留为智能指针类的成员,并且必须使用指向它的指针(或引用),该指针可以在复制时传递给新的智能指针。它通常由智能指针的第一个实例分配,该实例由对象指针构造(或自身构造),并在引用计数降至零时删除。

这里是我在其中一本书中找到的一个用于引用计数智能指针的实现。

template <typename T> class SmartPointer {
public:
    explicit SmartPointer(T* memory);
    SmartPointer(const SmartPointer& other);
    SmartPointer& operator =(const SmartPointer& other);
    ~SmartPointer();
    T& operator * () const;
    T* operator -> () const;
private:
    struct Intermediary {
        T* resource;
        size_t refCount;
    };
    Intermediary* data;
};

您可以看到Intermediary是在堆上分配的,而不是在堆栈上。原因如下-

假设您有两个智能指针指向同一个共享资源。如果其中一个智能指针超出了作用域,而在堆栈上定义了类型为Intermediarydata,则data将被清除,因此另一个智能指示器将不再知道引用计数或资源。为了使data对象即使在其中一个智能指针超出范围后仍然存在,您必须在堆上分配它。这样,即使共享资源的智能指针之一超出范围,data也会保留。

当引用计数与托管资源本身一起变为0时,Data将被清除。

引用计数指针的规则为:

  • 当你复制它时,引用计数会上升
  • 删除它时,引用计数会下降
  • 如果您将其分配给另一个(operator=),则将引用计数减少到您持有的引用计数,并获取您现在分配给的引用计数的计数器,然后将其增加
  • 如果将其重置为指向一个新对象,则需要一个新的计数器
  • 如果在任何时候减少引用计数,它就会降到0,则需要删除基础对象

现在让我们看看它是如何进行复制和赋值的:这个引用计数指针有很多副本,每个副本都有相同的计数器,具有相同的值。因此,"对象"不仅通过有许多指向它的指针来共享,而且它的计数器也是如此。因此,它也是一个指针。

在您的示例中,当我执行++(*count)时,指针本身没有变化,但它所指向的值增加了1,不仅在这个shared_ptr中,而且在指向同一对象的所有其他指针中。

我上面的第三条和第四条规则(可能需要指向不同的计数器)也说明了为什么它不能作为参考。