c++ - enable_shared_from_this 可以在没有继承的情况下使用吗?

标签 c++ inheritance destructor shared-ptr member

我找到的关于 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 关系?

最佳答案

is there a way to use enable_shard_from_this as a has-a relationship instead of an is-a relationship?

没有。

enable_shared_from_this 应该用作基类,因此在这种情况下,盲目地应用适用于其他情况的指南是行不通的。

即使有充分的理由想要这样做(但没有),它也不会奏效。导致 enable_shared_from_this 的魔法基地与shared_ptr共享所有权拥有派生对象的对象通过检查继承来工作。

enable_shared_from_this无论如何都不对 IS-A 关系建模,因为它没有根据虚函数定义的接口(interface)。 IS-A 表示扩展基接口(interface)的派生类型,但这里不是这种情况。 Good IS-NOT-A enable_shared_from_this<Good> .

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

  1. enable_shared_from_this doesn't have a virtual destructor

除非您计划通过指向 enable_shared_from_this 的指针删除对象,否则虚拟析构函数是无关紧要的。基类,这太疯狂了。没有理由绕过 Good作为指向 enable_shared_from_this<Good> 的指针基类,更没有理由使用 delete在该基指针上(通常类型会在创建后立即存储在 shared_ptr<Good> 中,因此您根本不会使用 delete)。

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

此外,作为 n.m.上面评论过,析构函数是 protected ,因此您不能通过基类删除它,即使您尝试过( protected 析构函数是防止这种类型的混合类滥用的惯用方法非多态基类)。

  1. The enable_shared_from_this destructor destroys *this, meaning it must always be the last destructor called

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

  1. Inheritance from two classes that both inherit from enable_shared_from_this can become a bit of a sticking point

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

关于c++ - enable_shared_from_this 可以在没有继承的情况下使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34042589/

相关文章:

c++ - 将 CComBSTR 与 NULL 进行比较

c++ - 函数调用中的隐式析构函数执行

c++ - 这个模式是什么意思?新的 (&entries[num_entries]) 项目;

c++ - 如何在lambda中访问捕获的此指针的 `typeid`?

c++ - 是否有可能在 C++ 中完全避免 C 风格的转换?

java - Java 中有没有一种方法可以基于 java.lang 基本类型(例如 String)构建自定义类型?

c++ - 无法从派生类中的友元函数访问类中声明的 protected 成员

java - 方法链+继承不能很好地结合在一起?

c++ - 非虚平凡析构函数+继承

c++ - 有条件的平凡析构函数