enable_shared_from_this
助手包含在创建对象的共享指针时设置的弱指针。这意味着引用计数(使用make_shared
单独分配或与对象一起分配)和对象中的额外weak_ptr
。
现在为什么不简单地包含引用计数呢?从哑指针设置shared_ptr
时,必须完全定义类型,因此shared_ptr
构造函数或赋值运算符可以检测从enable_shared_from_this
派生的类型并使用正确的计数器和格式可以保持不变,所以复制并不在乎。实际上,shared_ptr
已经必须检测它以设置嵌入式weak_ptr
。
答案 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_shared
为enable_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
的实例。