我发现的enable_shared_from_this
示例显示它是通过继承使用的。例如:
struct Good : enable_shared_from_this<Good> {
shared_ptr<Good> getptr() {
return shared_from_this();
}
};
int main() {
// Good: the two shared_ptr's share the same object
shared_ptr<Good> gp1(new Good);
shared_ptr<Good> gp2 = gp1->getptr();
cout << "gp2.use_count() = " << gp2.use_count() << endl;
}
我一天被警告过很多关于继承标准库的危险。这段代码当然似乎分享了这些危险,例如:
struct A : enable_shared_from_this<A> {};
struct B : enable_shared_from_this<B> {};
如果我想创建struct C : A, B {};
,那么粘着点显然是C::shared_from_this()
。显然我们可以解决这个问题,但有一些固有的复杂性。
所以我的问题是,有没有办法将enable_shard_from_this
用作has-a关系而不是is-a关系?
答案 0 :(得分:3)
有没有办法将
enable_shard_from_this
用作has-a关系而不是is-a关系?
没有
enable_shared_from_this
假设被用作基类,所以盲目地应用针对其他情况的指南在这种情况下不起作用。
即使有充分的理由想要这样做(并且没有)它也不会起作用。导致enable_shared_from_this
基础与拥有派生对象的shared_ptr
共享所有权的魔力通过检查继承而起作用。
enable_shared_from_this
无论如何都不建模IS-A关系,因为它没有根据虚函数定义的接口。 IS-A表示扩展基本接口的派生类型,但这不是这种情况。 Good
IS-NOT-A enable_shared_from_this<Good>
。
即。使用继承并不总是意味着IS-A关系。
- enable_shared_from_this没有虚拟析构函数
醇>
虚拟析构函数是无关紧要的,除非您计划通过指向enable_shared_from_this
基类的指针删除该对象,这将是疯狂的。没有理由传递Good
作为指向enable_shared_from_this<Good>
基类的指针,更不用说在该基指针上使用delete
(通常会存储类型)在shared_ptr<Good>
创建后,您就永远不会使用delete
。
enable_shared_from_this
是一个mixin类型,而不是一个抽象基础。它提供了shared_from_this
(以及很快weak_from_this
)成员,这就是全部。您不应将其用作抽象基类或接口类型,也不应使用基类型来访问派生类型的多态行为。它根本没有虚函数,而不仅仅是没有虚析构函数,应该告诉你。
此外,正如上午如上所述,析构函数受到保护,因此即使您尝试过,也无法通过基类删除它(受保护的析构函数是防止滥用mixin类的惯用方法是非多态的基类)。
- 的析构函数 醇>
enable_shared_from_this
析构函数会破坏*this
,这意味着它必须始终是最后一个名为
咦?不确定你的意思,但除了自己和自己的数据成员之外,它不负责销毁任何东西。
- 继承自
醇>enable_shared_from_this
的两个类的继承可能会成为一个棘手的问题
它应该工作正常(尽管如果没有一个明确的基类是enable_shared_from_this
的特化,你可能无法获得神奇的所有权共享)。 GCC标准库有一个错误(现已修复)无法编译,而不是仅仅无法共享所有权,但enable_shared_from_this
没有问题。