【问题标题】:Shared Smart Pointer Implementation with Reference Counting使用引用计数的共享智能指针实现
【发布时间】:2015-06-24 15:16:53
【问题描述】:

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

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

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

【问题讨论】:

    标签: c++ smart-pointers


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

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

        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 仍然存在。

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

        【讨论】:

          【解决方案4】:

          引用计数指针的规则是:

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

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-07-25
            • 2015-10-30
            相关资源
            最近更新 更多