10

据我了解make_shared<T>(...),可能会提供一些内存分配优化(它可能会在与 T 类实例相同的内存块内分配引用计数器)。

enable_shared_from_this 是否提供相同的优化?所以:

class T : std::enable_shared_from_this<T> {};
...
auto t = std::shared_ptr<T>(new T);

是相同的:

class T {};
...
auto t = std::make_shared<T>();

如果不考虑 sizeof(T)。

4

1 回答 1

9

enable_shared_from_this 是否提供相同的优化?所以:

不。从标准中的措辞可以看出,enable_shared_from_this<T>有一个weak_ptr<T>数据成员。这将 a 添加weak_ptr<T>到类中,该类具有指向包含引用计数的控制块的指针。它不直接包含引用计数。包含引用计数的控制块仍然存在于对象外部。

包含引用计数的控制块必须比对象生存得更久,以便其他weak_ptr曾经引用该对象的对象仍然可以访问控制块,以检查它是否已过期。

如果控制块在对象内部,那么它将在对象被销毁时被销毁,并且悬空weak_ptr无法安全地确定对象是否已过期。理论上,控制块的内存可以保持分配状态并且仍然可以使用,并且引用计数会更新,即使它们所属的对象已被破坏,但这看起来很丑陋(这意味着对象不会被delete,它需要显式的析构函数调用和显式operator delete调用来释放内存)。

如果所有权是使用自定义删除器或自定义分配器创建的,您也不能使用嵌入式控制块shared_ptr ,因为这些对象的大小不会事先知道。在这种情况下,除了嵌入在基类中的控制块之外,您仍然需要分配一个外部控制块,从而enable_shared_from_this<T>浪费更多空间。

于 2016-07-15T13:35:19.850 回答