enable_shared_from_this 和 make_shared 是否提供相同的优化
Does enable_shared_from_this and make_shared provide the same optimization
据我了解,make_shared<T>(...)
可能会提供一些内存分配优化(它可能会在与 class 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)。
Do enable_shared_from_this provides the same optimization? So:
没有。从标准中的措辞可以看出,enable_shared_from_this<T>
有一个 weak_ptr<T>
数据成员。这向 class 添加了一个 weak_ptr<T>
,它有一个指向包含引用计数的控制块的指针。它不直接包含引用计数。包含引用计数的控制块仍然存在于对象外部。
包含引用计数的控制块必须比该对象活得更久,以便其他 weak_ptr
曾经引用该对象的对象仍然可以访问该控制块,以检查它是否已过期。
如果控制块在对象内部,它会在对象被销毁时被销毁,并且悬空 weak_ptr
无法安全地确定对象是否已过期。从理论上讲,控制块的内存可以保持分配状态并继续使用,并且引用计数会更新,即使它们所属的对象已被销毁,但这看起来很丑陋(这意味着该对象不会被销毁 delete
,它需要显式的析构函数调用和显式的 operator delete
调用来释放内存。
如果所有者 shared_ptr
是使用自定义删除器或自定义分配器创建的,您也无法使用嵌入式控制块,因为这些对象的大小无法提前得知。在这种情况下,除了 嵌入 enable_shared_from_this<T>
基础 class 之外,你仍然需要分配一个外部控制块 ,浪费更多 space.
据我了解,make_shared<T>(...)
可能会提供一些内存分配优化(它可能会在与 class 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)。
Do enable_shared_from_this provides the same optimization? So:
没有。从标准中的措辞可以看出,enable_shared_from_this<T>
有一个 weak_ptr<T>
数据成员。这向 class 添加了一个 weak_ptr<T>
,它有一个指向包含引用计数的控制块的指针。它不直接包含引用计数。包含引用计数的控制块仍然存在于对象外部。
包含引用计数的控制块必须比该对象活得更久,以便其他 weak_ptr
曾经引用该对象的对象仍然可以访问该控制块,以检查它是否已过期。
如果控制块在对象内部,它会在对象被销毁时被销毁,并且悬空 weak_ptr
无法安全地确定对象是否已过期。从理论上讲,控制块的内存可以保持分配状态并继续使用,并且引用计数会更新,即使它们所属的对象已被销毁,但这看起来很丑陋(这意味着该对象不会被销毁 delete
,它需要显式的析构函数调用和显式的 operator delete
调用来释放内存。
如果所有者 shared_ptr
是使用自定义删除器或自定义分配器创建的,您也无法使用嵌入式控制块,因为这些对象的大小无法提前得知。在这种情况下,除了 嵌入 enable_shared_from_this<T>
基础 class 之外,你仍然需要分配一个外部控制块 ,浪费更多 space.