2016-06-16 1 views
0

は、私はクラスがあるとします。C++で共有/弱ポインタ​​を使用して互いに参照する2つのオブジェクトをきれいに実装する方法はありますか?

class Entity { 
    vector<weak_ptr<Entity> > aboveMe; 
    vector<weak_ptr<Entity> > belowMe; 

    void addBelow(weak_ptr<Entity> below) 
    { 
     belowMe.push_back(below); 
    } 

    void addAbove(weak_ptr<Entity> above) 
    { 
     aboveMe.push_back(below); 
    } 
} 

これは常に真でなければならない:

If an Entity A is above an Entity B, B is below A and vice versa. 

これを表現するための最もエレガントな方法は何でしょうか?

a->addBelow(b). 

しかし、不変に違反し

b->addAbove(a) 

に対応するコールなし:

は現在、それは単に呼び出すために、クライアントコードが可能です! Javaでは

、一つはこのようなものだろう:

void addBelow(Entity below) 
{ 
    belowMe.add(below); 
    below.addAbove(this); // With obviously some mechanism to prevent infinite recursion 
} 

共有/弱いポインタを使用する際にC++でこれを行うための最善の方法は何を?

+0

あなたの 'Entity'ストアはすべてより大きな構造になっていますか?もしそうなら、共有/弱ポインタ​​の代わりに['reference_wrapper'](http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper)を格納することができます。それ以外の場合は、['enable_shared_from_this'](http://en.cppreference.com/w/cpp/memory/enable_shared_from_this)をご覧ください。 – Holt

+0

はい、オブジェクトはshared_ptr のベクトルとして格納と割り当てを処理するより大きい「シーンモデル」オブジェクトに格納されます。それらのunique_ptrを作成し、それらのreference_wrappersを使用してオブジェクト間の参照を作成する必要がありますか? – user1582024

+0

これらのオブジェクトが他の場所の 'shared_ptr'に既に格納されている場合は、' enable_shared_from_this'を使うべきです(Smeeheeyの答えを参照)。 – Holt

答えて

2

C++でも同様のアプローチを使用できます。オブジェクトはその寿命が共有ポインタで管理しているように設計されている場合、それはそうのように、テンプレートクラスstd::enable_shared_from_thisから継承することができます。

class Entity : public std::enable_shared_from_this<Entity> { ... 

その後、thisポインタから安全に共有ポインタを作成することができます。次に、アプローチ:

void addBelow(weak_ptr<Entity> below) 
{ 
    belowMe.push_back(below); 
    below.addAbove(shared_from_this()); 
} 

は、必要なものに近いでしょう。

ここで指摘しておきたいことは、チェーンのオブジェクト間に所有関係がないため、オブジェクトが外部から「所有」されていれば、これは機能します。あなたは、あなたがさらにあなたのチェーンを変更することができ、所有権の階層を許可したい場合は

ように、オブジェクト自身の下に ':

vector<weak_ptr<Entity> > aboveMe; 
vector<shared_ptr<Entity> > belowMe; 

注:あなたは確かに、その後、両方向の共有ポインタを望んでいないだろうオブジェクトが解放されることのない循環的な所有権が得られます。

注2:shared_ptrクラスはweak_ptr参照から構築できます。逆も同様です。したがって、上記のaddBelowの提案を選択した所有権の階層に関係なく、変更を加えることなく動作します。

+1

関数メンバーを呼び出す場合は、shared_ptrを取得するにはlock()を下に設定する必要があります – gbehar

+0

これは機能します!はい、オブジェクトは別のオブジェクトによって所有されています。ありがとうございました! – user1582024

関連する問題