c++ - 如何在父类和子类中使用std::enable_shared_from_this?

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

我有两个类AB,其中BA的子类。我需要两个类都可以使用std::enable_shared_from_this

我尝试了这个:

#include <memory>
#include <iostream>
#include <vector>


class A : public std::enable_shared_from_this<A> {
  public:
    void insertme(std::vector<std::shared_ptr<A>>& v) {
        std::cout << "A::insertme\n";
        v.push_back(shared_from_this());
        std::cout << "OK\n";
    }
};

class B : public A, public std::enable_shared_from_this<B> {
  public:
    void insertme(std::vector<std::shared_ptr<B>>& v) {
        std::cout << "B::insertme\n";
        v.push_back(std::enable_shared_from_this<B>::shared_from_this());
        std::cout << "OK\n";
    }
};

int main()
{
    std::vector<std::shared_ptr<A>> va;
    std::vector<std::shared_ptr<B>> vb;

    std::shared_ptr<A> pa = std::make_shared<A>();
    std::shared_ptr<B> pb = std::make_shared<B>();

    pa->insertme(va);
    pb->insertme(vb);
}

(为了避免shared_from_this()含糊不清,我必须在B::insertme中完全限定它。)

当我运行上面的程序时,得到以下输出:
A::insertme
OK
B::insertme
terminate called after throwing an instance of 'std::bad_weak_ptr'
  what():  bad_weak_ptr
Aborted (core dumped)

因此,A::insertme有效,但B::insertme无效。

我在Linux下使用GCC 9.1.0。

我究竟做错了什么?

最佳答案

您只需要(并且只能)从基类的shared_from_this继承:

class A : public std::enable_shared_from_this<A> {
  public:
    void insertme(std::vector<std::shared_ptr<A>>& v) {
        std::cout << "A::insertme\n";
        v.push_back(shared_from_this());
        std::cout << "OK\n";
    }
};

class B : public A {
  public:
    void insertme(std::vector<std::shared_ptr<B>>& v) {
        std::cout << "B::insertme\n";
        v.push_back(shared_from_this()->static_pointer_cast<B>());
        std::cout << "OK\n";
    }
};

这意味着您需要显式的static_pointer_cast来获取shared_ptr<B>,但是如果需要,可以将其包装在B中的替代项中:
std::shared_ptr<B> shared_from_this() { return A::shared_from_this()->static_pointer_cast<B>(); }

关于c++ - 如何在父类和子类中使用std::enable_shared_from_this?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60729329/

相关文章:

java - 继承的选择

python - Mixin 覆盖继承的方法

c++ - 将字符串转换为 double 的最佳方法?

c++ - llvm JIT 将库添加到模块

python - 使用 SWIG 包装共享指针对象不授予对类成员函数的访问权限

c++ - 在两个 lambda 之间共享对象

android - 在圆周上添加 Sprite

c++ - 如何在 Raspberry Pi 上拥有类似智能手机/平板电脑的 GUI?

C++ Push_back复制对象而不是引用

派生自同一个类的类的 C++ 子类