2

我有两个类,A并且的子类B在哪里。我需要两个类来使用.BAstd::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。

我究竟做错了什么?

4

2 回答 2

4

您只需要(并且只能)从基类中的 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(std::static_pointer_cast<B>(shared_from_this()));
        std::cout << "OK\n";
    }
};

这意味着您需要显式static_pointer_cast获取 a shared_ptr<B>,但如果您愿意,可以将其包装到覆盖中B

std::shared_ptr<B> shared_from_this() { return std::static_pointer_cast<B>(A::shared_from_this()); }
于 2020-03-17T20:07:25.200 回答
0

只有当类类型恰好继承了一个明确的公共基础时,才会在创建enable_shared_from_this<X>a 时设置到该对象的自动链接。但是继承了两个不同的基础。shared_ptr<T>Tenable_shared_from_thisBenable_shared_from_this

相反,您可以只使用enable_shared_from_this<A>, 并编写一个B::shared_from_this()使用 的自定义A::shared_from_this()

class B : public A {
  public:
    // These hide the A::shared_from_this(), but they can still be
    // used by qualification if wanted.
    std::shared_ptr<B> shared_from_this()
    { return std::static_pointer_cast<B>(A::shared_from_this()); }
    std::shared_ptr<const B> shared_from_this() const
    { return std::static_pointer_cast<B>(A::shared_from_this()); }

    // ...
};
于 2020-03-17T20:09:39.100 回答