2016-03-23 17 views
1

私のプロジェクトの1つでは、オブジェクトのインメモリインデックスを作成したいという状況に遭遇しました。プライマリインデックスは異なるキーを使用し、セカンダリインデックスはいくつかの他の要素をキーとして使用します。 私はその後コンテナ間でオブジェクトを共有する最適な方法は何ですか?

std::map<string, Object> 

(再びすべてのオブジェクトは一意で検討たとえばSTD ::マップ)別の容器を使用してセカンダリインデックスのための参照/ポインタを格納するための最良の方法ですとしてプライマリインデックスのためstd::mapを使用していた場合オブジェクトの追加コピーを作成することなく、

(私はオブジェクトがプライマリインデックスから削除されるとき、理想的に、ケアはまた、二次インデックスから削除するには取られるべきであることを知っているダングリングポインタまたは参照のリスクをもたらす生のポインタや参照を使用して
  • だろうが、ポインタ/主要指数のコンテナは、内部で自身を調整するとき、二次指数の参照は無効?)

    std::map<string, const Object*>

  • またはプライマリインデックスとのweak_ptrのセカンダリインデックス std::map<string, std::shared_ptr<Object>> // primary index std::map<string, std::weak_ptr<Object>> // secondary index
  • でのshared_ptrの組み合わせを使用して

私は両方のアプローチについて長所と短所があることを知っています。特に、プライマリコンテナにオブジェクトを直接挿入する柔軟性を失いたくはありませんが、セカンダリインデックスでオブジェクトを再度コピーすることは望ましくありません。セカンダリインデックスのためだけにスマートポインタを使用することの難しさは、オブジェクトを所有しないことです。

ご協力いただきありがとうございます。

+1

主キーを使用してオブジェクトを参照するのはどうですか? 'std :: map //セカンダリインデックス、値はプライマリキー'です。この点の欠点は、オブジェクトを取得するために別のマップルックアップが必要なことです。 :P –

+0

Objectへの複数ステップの参照がありますか?コストはほぼ倍増するでしょう。 –

+0

オブジェクトへのスマートポインタの使用をお勧めします。ポインタを 'std :: vector'に配置します。次に、インデックスを作成します。キーとオブジェクトへのスマートポインタを使用して、 'std :: map'を呼び出します。 –

答えて

1

オブジェクトをいくつかのコンテナに置きます。オブジェクトの追加/削除の頻度に応じて、std::liststd::dequeのように、その要素への参照を無効にしないコンテナを使用することを検討してください。

あなたの地図では、参照を使用してオブジェクト(またはそのメンバー)を参照するだけです(std::reference_wrapperを使用)。

オブジェクトを追加または削除するたびに、インデックスから無効な参照を削除したり、新しい参照を追加したりするように、バックエンドストレージとインデックスをカプセル化します。

これで、オブジェクトを一度保存​​してスマートポインタを使用するだけで済みます。これは明らかにオブジェクトを実際に所有し、そのライフタイムを制御し、インデックスをカプセル化したままにしておくことができれば(更新を維持するために)のみ機能します。

関連する問題