1. ホーム
  2. c++

[解決済み] std::shared_ptr of this

2022-07-25 11:32:39

質問

現在、スマートポインタの使い方を勉強しています。しかし、いくつかの実験を行っているときに、私は満足のいく解決策を見つけることができない、次のような状況を発見しました。

クラス A のオブジェクトがクラス B (子) のオブジェクトの親であり、両方が互いを知っている必要があると想像してください。

class A;
class B;

class A
{
public:
    void addChild(std::shared_ptr<B> child)
    {
        children->push_back(child);

        // How to do pass the pointer correctly?
        // child->setParent(this);  // wrong
        //                  ^^^^
    }

private:        
    std::list<std::shared_ptr<B>> children;
};

class B
{
public:
    setParent(std::shared_ptr<A> parent)
    {
        this->parent = parent;
    };

private:
    std::shared_ptr<A> parent;
};

問題は、クラスAのオブジェクトが、どのようにして std::shared_ptr を渡すことができるのでしょうか? this ) をその子に送るか?

Boost共有ポインタに対する解決策があります ( を取得する boost::shared_ptr に対して this ) を使って処理する方法ですが std:: スマートポインターを使用してどのように処理するのでしょうか?

どのように解決するには?

あるのは std::enable_shared_from_this があります。これを継承して .shared_from_this() をクラス内部から呼び出すことができます。また、ここでは循環的な依存関係を作っているので、リソースリークにつながる可能性があります。これは std::weak_ptr . したがって、あなたのコードは次のようになります(子供は親の存在に依存し、その逆はないと仮定します)。

class A;
class B;

class A
    : public std::enable_shared_from_this<A>
{
public:
    void addChild(std::shared_ptr<B> child)
    {
        children.push_back(child);

        // like this
        child->setParent(shared_from_this());  // ok
        //               ^^^^^^^^^^^^^^^^^^
    }

private:     
    // note weak_ptr   
    std::list<std::weak_ptr<B>> children;
    //             ^^^^^^^^
};

class B
{
public:
    void setParent(std::shared_ptr<A> parent)
    {
        this->parent = parent;
    }

private:
    std::shared_ptr<A> parent;
};

ただし .shared_from_this() を呼び出すには this が所有する std::shared_ptr が呼び出された時点で所有されます。これは、スタック上にそのようなオブジェクトをもう作れないことを意味し 一般に を呼び出すことはできません。 .shared_from_this() をコンストラクタやデストラクタの中から呼び出すことはできません。