3

質問があります。各レベルで異なるクラスを使用してツリーを実装しました。ツリー項目へのポインターは boost::shared_ptr<> です。

各レベルには親へのポインターとその子へのポインターが格納されるため、ヘッダー ファイルには循環依存関係があります。

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

//A.hpp
class A
{
    List<boost::shared_ptr<B> > children;
};

//B.hpp
class B{
   boost::shared_ptr<A> parent;

};

boost::shared_ptr を使用しているため、B.hhp で前方宣言を使用できません。しかし、私はこの問題を解決する方法がわかりません。助けていただければ幸いです。

4

4 に答える 4

5

boost::shared_ptr を使用しているため、B.hhp で前方宣言を使用できません

本当じゃない。a を宣言するshared_ptr<>ために、指定された型が完全である必要はありません。

#include <boost/shared_ptr.hpp>

class A;

int main()
{
    boost::shared_ptr<A> pA; // OK
}

class A { };

あなたの問題は、ヘッダーファイルへの相互依存ではありません。前方宣言を使用して、これらの依存関係を断ち切ることができます。

あなたが抱えている問題は、お互いを生かし続けるオブジェクト間の循環参照です。このサイクルを断ち切るには、 を使用しますboost::weak_ptr

また、C++11 では標準のクラス テンプレートstd::shared_ptrstd::weak_ptr(ヘッダーで定義されている<memory>) が導入されているため、C++03 を使用している場合を除き、Boost のものではなくこれらのクラス テンプレートを使用することを検討する必要があります。

//A.hpp
class A
{
    List<boost::shared_ptr<B> > children;
};

//B.hpp
class B{
   boost::weak_ptr<A> parent;
};
于 2013-02-22T20:57:41.793 に答える
2

サイクルを断ち切るにはboost::weak_ptrinを使用する必要があります。B

//A.hpp
class A
{
    List<boost::shared_ptr<B> > children;
};

//B.hpp
class B
{
   boost::weak_ptr<A> parent;
};

メソッドで変換できboost::shared_ptr<A>ますlock()

于 2013-02-22T20:57:14.150 に答える
0

子から親へのポインター (ツリーを「上る」もの) は、代わりにboost::weak_ptrにする必要があります。これにより、boost::shared_ptrs (weak_ptr::lock() 関数を介して) を介して親へのアクセスを維持しながら、循環依存関係を効果的に解消できます。

于 2013-02-22T20:58:03.650 に答える
0

これは、スマート ポインターを使用した従来の方法です。weak_ptr依存関係を壊すには、何らかの方向で何らかの方法で使用する必要があります。

それが機能する方法は、ポイントされたオブジェクトへの参照を保持weak_ptrしないことです。ただし、その関数shared_ptrを呼び出すことで、いつでもを取得できます。何らかの理由で有効期限が切れた.lock()呼び出さないように注意する必要があります。.lock() shared_ptr

私がこのメカニズムを使用する方法は次のとおりです。常に親から子へ a を保持し、shared_ptr常に子から親へa を保持weak_ptrします。したがって、階層に戻るハードリンクを実行できないため、循環依存関係はありません。

この方法は理にかなっています (ただし、特定の状況によって異なる場合があります): 子が存在する場合、親も存在する必要があるため、 の呼び出しは失敗.lock()weak_ptrません。

Boostweak_ptrのドキュメントなどで詳細を確認できます。

于 2013-02-22T21:02:52.523 に答える