2016-05-22 12 views
0

Entityオブジェクトの唯一の所有者はEntityManagerです。unique-owner-collectionからweak_ptrまたはshared_ptrを返す必要がありますか?

class EntityManager 
{ 
    public: 
    std::weak_ptr<Entity> vs std::shared_ptr<Entity> getEntityByID(int ID) const; 
    private: 
    std::vector<std::shared_ptr<Entity>> entities; 
}; 

Entityは、プログラムで使用する必要があり、それがgetEntityByID機能を使用することによりEntityManagerから受信します。 EntityManagerは所有者のみであるため、

Entityは、しかし、それはとweak_ptrとして多くの場所に保存されていることができ、shared_ptrなどのプログラムの他の場所に格納すべきではありません。

getEntityByIDは、戻り値としてweak_ptrを使用するためのweak_ptrまたはshared_ptr

私の引数を返す必要があり、場合私の質問は次のとおりです。

  • それはweak_ptrをエンティティを取得した後に使用する必要があることをgetEntityByID関​​数のシグネチャで明らかです。戻り値としてshared_ptrを使用するための

マイ引数:

  • weak_ptrはとにかくshared_ptrに変換することができ、そして他の場所で shared_ptrのように保存することができます。さらに、すべての使用で、lock機能を使用してshared_ptrに変換されていました。
  • shared_ptrが使用されると、すべての機能では、それはちょうど shared_ptrを渡すことができます。 ptrを使うたびにlock関数を使う必要はもうありません。もしそれがポインタを格納するために を決定するなら、それは単にデータメンバとしてそれをweak_ptrにコピーするでしょう。
+0

'EntityManager'が一意の所有者である場合、' std :: vector 'を返し、参照を返してみませんか? –

+0

共有/弱ポインタ​​を使用しているのはなぜですか?呼び出し元がリソースが削除された後にポインタを使用しようとする可能性はありますか? – Galik

+4

または一意のポインタのベクトルと借用された生ポインタを返します。 – Flexo

答えて

0

EntityManagerがエンティティの唯一の所有者であるとした場合、エンティティをshared_ptrではなくunique_ptrとして保存する必要があります。 unique_ptrのベクトルに変更したら、.get()メソッドから生ポインタを返すべきです。理想的には、EntityManagerはEntitiesをポインタではなくオブジェクトとして格納し、格納されたオブジェクトへの参照または参照の参照を返すことができます。

+0

コメントに書いたとおり、EntityManagerコレクションからEntityを削除できます。エンティティ(プレイヤー)が他のエンティティ(モンスター)でターゲットをロックすることができるように、エンティティへの参照はプログラム内に存在することができます。だから、私は共有ポインタと弱いポインタを使う。 –

+0

EntityManagerがshared_ptrとしてエンティティを格納し、getがweak_ptrを返す唯一のエンティティである場合、EntitieManagerのEntityを削除した後、weak_ptrはすべてlock()で失敗します。あなたの実装にweak_ptrが必要な場合、それはあなたが悪い設計をしていることを意味します。 – paweldac

+0

"EntitieManagerでEntityを削除した後、すべてのweak_ptrはlock()で失敗します - はい、プログラム内の予測状況。 「あなたの実装にweak_ptrが必要な場合は、Entity(Human)が存在し、ロックされたターゲットへの参照を格納するRocket(Human)があるとします。目標とする参照(Rocket内)が未処理のポインタまたは参照が使用される場合、Humanが死亡した場合、Rocketは無効なオブジェクトへの参照を格納します。 shared_ptrが使用され、人間が死ぬと、それは人間の生命を前もって延ばすだろう。 –

0

shared_ptrは共有所有です。 shared_ptr csnに格納されているオブジェクトは、オブジェクトの存続期間を決定する一意の権利を持っているとみなされません。彼らはshared_ptrに変換し、それを使用している間、誰かが中央マネージャでそれを削除しようとする可能性がありそれを使ういつでも誰もが、weak_ptrを格納している場合でも

。 「一時的な」shared_ptrが存在するため、これは失敗します。

中規模の複雑な状況では、これは簡単なテストでは公開されないため、後でバグの理由を説明するのが難しくなります。

これを解決するにはweak/sharedを使用できますが、実装の詳細としてのみ使用できます。つまり、スマートポインタの上にセマンティクスを適用する必要があります。そして、それらのセマンティクスは、使用されるスマートポインタを決定するでしょう。

+0

はい、私はこの面から見ていません。私はその "ユニークな"と思ったのは、 'EntityManager'だけがそれをshared_ptrとして保存すべきだからです。たとえ関数が一時的にスタックに格納しても、それは一時的な所有者です。 "shared_ptr csnnotに格納されているオブジェクトは、オブジェクトの存続期間を決定する一意の権利を持っているとみなします" - true。だからあなたは、その状況でgetEntityByID関​​数からshared_ptrを返さなければならないと思いますか? –

関連する問題