2

と の 2 つのクラスがAありBBは のサブクラスですA。使用するには両方のクラスが必要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 を使用しています。

私は何を間違っていますか?

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これは、を取得するために明示的なものが必要であることを意味しますが、必要に応じて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>が作成されたときに設定されるへの自動リンケージshared_ptr<T>は、クラス タイプが明確なパブリックベースTを 1 つだけ継承する場合にのみ機能します。enable_shared_from_thisしかし、 2 つの異なるベースBを継承します。enable_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 に答える