7

私は現在、に大きく依存するアプリケーションをまとめており、shared_ptrこれまでのところすべてがうまくいっているようですshared_ptr.

最も認識されている問題の 1 つは、循環依存関係です。これらの問題は、チェーンのオブジェクトの有効期間に影響を与えないshared_ptrを格納することで解決できます。weak_ptrただし、外部オブジェクトへのポインターを a 経由で保存する必要がある場合に頭を悩ませていますweak_ptr-それが禁止されているのか、推奨されていないのか、それとも安全なのかわかりませ

次の図は、私が何を意味するかを説明しています (黒い矢印は を示しshared_ptr、破線は を示しますweak_ptr)。

代替テキスト http://img694.imageshack.us/img694/6628/sharedweakptr.png

  • 親にはshared_ptr、 を使用して親を指す 2 つの子へのが含まれますweak_ptr
  • 最初の子のコンストラクターで、親を介して2 番目の子weak_ptrへのポインターを取得し、それをローカルに保存します。

コードは次のようになります。

#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/enable_shared_from_this.hpp>

class child;
class child2;
class parent;

class parent : public boost::enable_shared_from_this<parent>
{
public:
    void createChildren()
    {
        _child2 = boost::make_shared<child2>(shared_from_this());
        _child = boost::make_shared<child>(shared_from_this());
    }

    boost::shared_ptr<child> _child;
    boost::shared_ptr<child2> _child2;
};

class child
{
public:
    child(boost::weak_ptr<parent> p)
    {
        _parent = p;
        _child2 = boost::shared_ptr<parent>(p)->_child2; // is this safe?
    }

    boost::weak_ptr<parent> _parent;
    boost::shared_ptr<child2> _child2;
};

class child2
{
public:
    child2(boost::weak_ptr<parent> p)
    {
        this->_parent = p;
    }

    boost::weak_ptr<parent> _parent;
};

int main()
{
    boost::shared_ptr<parent> master(boost::make_shared<parent>());
    master->createChildren();
}

私はこれをテストしましたが、問題なく動作しているようです(メモリ リークの報告はありません) が、私の質問は次のとおりです: これは安全ですか? もしそうでなければ、なぜですか?

4

3 に答える 3

6

子コンストラクターは、呼び出している方法で安全であるように見えます。ただし、一般的には安全ではありません。

この問題は、子コンストラクターの引数としてweak_ptrを渡すことが原因です。これは、弱いポインタがもはや存在しないオブジェクトに対するものであるかどうかを心配する必要があることを意味します。このパラメーターをshared_ptrsに変更し、保存時にweak_ptrに変換することで、オブジェクトがまだ存在していることがわかります。変更点は次のとおりです。

child(boost::shared_ptr<parent> p)
{
    _parent = p;
    _child2 = p->_child2; // This is this safe
}
于 2010-01-26T12:59:30.710 に答える
3

shared_ptr に関する最も認識されている問題の 1 つは、循環依存関係です。これらの問題は、チェーンの上流にあるオブジェクトの有効期間に影響を与えない weak_ptr を格納することで解決できます。

違う。この循環依存関係は存在するか、または存在しません。

問題が存在する場合、弱い参照は単にオプションではありません。

weak_ptr を介して外部オブジェクトへのポインターを格納する必要がある場合

weak_ptrほとんど必要ありません。

適切な非常に具体的なケースはほとんどありませんが、ほとんどはカルトweak_ptrの一部です。問題をランダムに投げる代わりに、ランダムに半分ずつ投げます( SO に見られるように)。shared_ptrshared_ptrshared_ptrweak_ptr

于 2011-10-08T05:57:43.817 に答える
0

'p' が (どういうわけか) 既に破棄されている場合、bad_weak_ptr 例外が発生します。したがって、子 ctor が例外を予期するのは安全ですが、それ以外の場合は安全ではありません。

于 2010-01-26T12:38:32.517 に答える