10

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

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

4

3 回答 3

7

The first thing that comes to mind is whether that approach would be feasible at all, and the answer is that it would not:

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

If the count is stored in the object, then no weak_ptr can outlive the object, which is a breach in the contract. The whole idea of weak_ptr is that they can outlive the object (if the last shared_ptr goes out of scope, the object is deleted even if there are weak_ptr)

于 2011-07-26T10:03:04.087 回答
1

要从将计数嵌入对象中获得任何好处,您需要取消 中的第二个指针shared_ptr,这会改变其布局,并且还会为创建析构函数对象带来问题。如果您更改布局,则此更改必须在shared_ptr使用的任何地方都可见。这意味着您不能有shared_ptr指向不完整类型的实例。

于 2011-07-26T09:52:02.880 回答
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。)

于 2011-07-26T08:05:28.887 回答