c++ - 没有enable_shared_from_this 可以实现shared_from_this 吗?

标签 c++ shared-ptr multiple-inheritance weak-ptr enable-shared-from-this

使用 enabled_shared_from_this 时似乎有一些边缘情况。例如:

boost shared_from_this and multiple inheritance

shared_from_this 是否可以在不使用 enable_shared_from_this 的情况下实现?如果是这样,它能做得同样快吗?

最佳答案

A shared_ptr是3件事。它是一个引用计数器、一个破坏者和一个拥有的资源。

当你make_shared ,它一次分配所有 3 个,然后在那个 block 中构造它们。

当您创建 shared_ptr<T>来自T* ,您单独创建引用计数器/销毁器,并注意拥有的资源是 T* .

shared_from_this的目标是我们可以提取一个shared_ptr<T>来自T*基本上(假设它存在)。

如果所有共享指针都是通过 make_shared 创建的,这很容易(除非您想要定义失败时的行为),因为布局很简单。

然而,并非所有共享指针都是以这种方式创建的。有时您可以创建一个共享指针,指向一个不是由任何 std 创建的对象。库函数,因此 T*与共享指针引用计数和销毁数据无关。

因为在 T* 中没有房间或者它指向什么(通常)找到这样的构造,我们必须将它存储在外部,这意味着全局状态和线程安全开销和其他痛苦。这对不需要的人来说是一种负担 shared_from_this ,并且与确实需要它的人(互斥锁、查找等)的当前状态相比,性能受到了影响。

当前的设计存储一个 weak_ptr<T>enable_shared_from_this<T> .这weak_ptr每当 make_shared 时被初始化或 shared_ptr<T>构造函数被调用。现在我们可以创建一个 shared_ptr<T>来自 T*因为我们通过继承 enable_shared_from_this<T> 在类里面为它“腾出了空间” .

这也是极低的成本,并且可以很好地处理简单的情况。我们最终得到一个开销 weak_ptr<T>超过 T 的基准成本.

当你有两个不同的 shared_from_this , 他们的 weak_ptr<A>weak_ptr<B>成员是不相关的,所以你想在哪里存储生成的智能指针(可能两者都有?)是不明确的。这种歧义会导致您看到错误,因为它假定只有一个 weak_ptr<?>。一个独特的成员shared_from_this<?>实际上有两个。

The linked solution提供了一种聪明的方法来扩展它。它写道 enable_shared_from_this_virtual<T> .

这里不是存储 weak_ptr<T> ,我们存储一个 weak_ptr<Q>其中 Qenable_shared_from_this_virtual<T> 的虚基类,并且在虚拟基类中唯一地这样做。然后它会非虚拟地覆盖 shared_from_this和类似的方法来提供与 shared_from_this<T> 相同的界面确实使用“成员指针或子类型 shared_ptr 构造函数”,您可以在其中以类型安全的方式将引用计数/破坏者组件与拥有的资源组件分开。

这里的开销大于基本shared_from_this : 它具有虚拟继承并强制使用虚拟析构函数,这意味着该对象存储指向虚拟函数表的指针,并可以访问shared_from_this。速度较慢,因为它需要虚函数表分派(dispatch)。

优点是它“可以正常工作”。现在有一个独特的 shared_from_this<?>在层次结构中,您仍然可以获得指向类的类型安全共享指针 T继承自 shared_from_this<T> .

关于c++ - 没有enable_shared_from_this 可以实现shared_from_this 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28052672/

相关文章:

python - 如何获得指向通用 PyObject* 内数据的指针?

c++ - 以第二种形式使用 QMediaPlayer

c++ - 为什么这个显式析构函数会导致共享 ptr 中的内存损坏?

android - 继承ActionBarSherlock和Android YouTubePlayer

c++ - Visual Studio 编译器警告 C4250 ('class1' : inherits 'class2::member' via dominance)

c++ - 对非常大的数字执行 nCr 和逆阶乘 (MODm)

c++ - 无法解释不明确的模板特化

c++ - shared_from_this 导致 bad_weak_ptr

c++11 - C++ 编译器错误 : “invalid declarator before”

python - 我怎么知道哪个基类将特定属性添加到子类对象