【问题标题】:Can enable_shared_from_this be Used Without Inheritance?可以在没有继承的情况下使用 enable_shared_from_this 吗?
【发布时间】:2016-03-06 16:26:52
【问题描述】:

我发现的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 关系?

【问题讨论】:

  • 关于第3点:没有enable_shared_from_this;有enable_shared_from_this&lt;D&gt;。这个很重要。如果A 派生自enable_shared_from_this&lt;A&gt;B 派生自enable_shared_from_this&lt;B&gt;,那么它们是不同的基类。
  • 这在实践中并不是一个常见的问题。如果这是一个问题,则表明复杂性已经存在:您过度使用 enable_shared_from_this 或者您的类层次结构应该更改为具有提供 shared_from_this 功能的单个基类。
  • 1.析构函数是受保护的,所以它不是虚拟的也没关系。无论如何,没有人可以直接调用它。 2.析构函数不会破坏*this。这不可以。 3.如果你看到一个症结,请指出它的确切位置。
  • 另见this。来自 enable_shared_from_this 的无限制多重继承不起作用,但随后将 shared_ptr 与无限制 MI 一起使用也不起作用,因此不会丢失任何价值。
  • 回复:“我在这一天被警告过很多关于从标准库继承的危险”,这太宽泛了。您应该被警告不要从非设计派生的事物中派生。 enable_shared_from_this 旨在派生自,对继承的一般恐惧不应成为决定是否以设计使用方式使用它的因素。

标签: c++ inheritance destructor shared-ptr member


【解决方案1】:

有没有办法将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 表示扩展基本接口的派生类型,但这里不是这种情况。 A Good IS-NOT-A enable_shared_from_this&lt;Good&gt;

即使用继承并不总是意味着 IS-A 关系。

  1. enable_shared_from_this 没有虚拟析构函数

除非您打算通过指向enable_shared_from_this 基类的指针来删除对象,否则虚拟析构函数是无关紧要的,这太疯狂了。没有理由将Good 作为指向enable_shared_from_this&lt;Good&gt; 基类的指针传递,更没有理由在该基指针上使用delete(通常该类型将存储在shared_ptr&lt;Good&gt; 中一旦它被创建,你就永远不会使用delete)。

enable_shared_from_this 是 mixin 类型,而不是抽象基类。它提供了shared_from_this(很快weak_from_this)成员,仅此而已。您不应将其用作抽象基类或接口类型,也不应使用基类来访问派生类型的多态行为。它根本没有虚函数,而不仅仅是没有虚析构函数,这一事实应该告诉你。

此外,作为 n.m.上面评论过,析构函数是受保护的,所以你不能通过基类删除它,即使你尝试过(受保护的析构函数是防止那种类型的 mixin 类误用的惯用方式。非多态基类)。

  1. enable_shared_from_this 析构函数销毁 *this,这意味着它必须始终是最后调用的析构函数

嗯?不确定你的意思,但它不负责销毁除了它自己和它自己的数据成员之外的任何东西。

  1. 从两个都继承自 enable_shared_from_this 的类的继承可能会成为一个症结

它应该可以正常工作(尽管如果没有一个明确的基类是enable_shared_from_this 的特化,您可能无法获得神奇的所有权共享)。 GCC 标准库有一个错误(现已修复),它无法编译,而不仅仅是无法共享所有权,但这不是 enable_shared_from_this 的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-09
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 2013-05-28
    • 2015-12-27
    相关资源
    最近更新 更多