为什么enable_shared_from_this嵌入弱指针而不是直接嵌入引用计数器?

时间:2011-07-26 07:58:07

标签: c++ c++11 shared-ptr

enable_shared_from_this助手包含在创建对象的共享指针时设置的弱指针。这意味着引用计数(使用make_shared单独分配或与对象一起分配)和对象中的额外weak_ptr

现在为什么不简单地包含引用计数呢?从哑指针设置shared_ptr时,必须完全定义类型,因此shared_ptr构造函数或赋值运算符可以检测从enable_shared_from_this派生的类型并使用正确的计数器和格式可以保持不变,所以复制并不在乎。实际上,shared_ptr已经必须检测它以设置嵌入式weak_ptr

3 个答案:

答案 0 :(得分:7)

首先想到的是这种方法是否可行,答案是不会:

struct X : enable_shared_from_this {};
std::shared_ptr<X> p( new X );
std::weak_ptr<X> w( p );
p.reset();                      // this deletes the object
if ( w.use_count() ) {          // this needs access to the count object
                                //    but it is gone! Undefined Behavior

如果计数存储在对象中,则没有weak_ptr可以超过对象,这是合同中的违规行为。 weak_ptr的整个想法是它们可以比对象寿命更长(如果最后shared_ptr超出范围,即使存在weak_ptr,对象也会被删除)

答案 1 :(得分:1)

问题分离:make_sharedenable_shared_from_this嵌入点数shared_from_this

没有理由将两者混合在一起:图书馆无法假设客户端代码对要求的要求。通过将两者分开,客户端代码可以选择最适合的任何内容。

此外,Boost(来自shared_ptr的地方)也提出intrusive_ptr

(请注意,您的建议似乎不允许自定义删除。您可以通过将enable_shared_from_this更改为template<typename T, typename Deleter = default_deleter<T>> class enable_shared_from_this; 来解决此问题,但此时它已接近重塑intrusive_ptr。)

答案 2 :(得分:1)

为了在计算对象中嵌入计数有任何好处,你需要 取消shared_ptr中的第二个指针 更改其布局,并为创建析构函数创建问题 宾语。如果更改布局,则必须显示此更改 使用shared_ptr的地方。这意味着你无法拥有 指向不完整类型的shared_ptr的实例。