2009-06-11 8 views
4

boost::ptr_vectorを使用し始めました。私は1つのクラスAのメンバーとしてptr_vector pctrを持っていて、別のクラスBがpctrの要素を参照したいと思っています。クラスBのオブジェクトを構築する際に、ポインタをpctrに保存したいと考えています。ブーストポインタコンテナ内の要素へのポインタ

ポインタコンテナはポインタへのアクセスを許可しません(ただし参照のみ)ので、pctrから参照のアドレスを取得し、それをタイプBのオブジェクトに格納する必要があります。直観的ではない。より良い選択肢がありますか?

+0

実際に同じ問題があります。私の以前のソリューション(明示的な削除を持つ生ポインタのベクトル)に戻ります。愚かな、本当に。 – Cookie

+0

@Cookie実際、今まで(2011年)私は多くのポインタコンテナを使用してきました。私はreference_wrapperを使用します。私はこれを私が取り組んでいるプロジェクトのwikiで説明しました:http://sourceforge.net/apps/mediawiki/crackpot/index.php?title=Boost_Pointer_Containers –

+0

良い点、ありがとう。余裕を持って自分を見つけた場合、3つの選択肢間のパフォーマンス比較がうまくいくかもしれません。 – Cookie

答えて

0

逆参照されたイテレータのアドレスを取ることは、あなたがしようとしていることを達成する正しい方法だと思います。

iterator it = ... 
T *ptr = &*it; 

しかし、AオブジェクトがBオブジェクトより先に破棄された場合、ポインタがつぶれてしまう可能性があるため、危険です。このため、呼び出し元がオブジェクトのアドレスを取得できるようにするrelease関数は、コンテナからポインタを削除します。

オーバーヘッドをサポートできる場合は、boost::ptr_vectorをスマートポインタのベクトルに変更することを検討してください。 std::vector<boost::shared_ptr<T> >

+0

ptr_vectorに対するイテレータのアドレスは、それ以上の挿入があれば変更され、無効になります。 –

+0

ですが、-1は私のものではありません(shared_ptrsのベクトルを使用することについてのあなたの声明は意味があります)。 –

2

あなたが発見したように、ブーストポインタコンテナはポインタをうまく保護します。 確かに、あなたはそれが降伏する参照のアドレスを取ることによってそれを敗北させることができますが、これらのポインタにぶら下がってポインタ容器の主張権の強さを薄めるかもしれないことに注意してくださいコードは本当に)。

選択肢があるように見えるでしょう:

  • が関心のポインタコンテナ要素を参照するクラスBホールドイテレータを持っている(もちろん、通常のイテレータの無効化規則は、対処される必要があります)。

  • Aはポインタを所有しているので、Bが何らかの非所有弱参照を保持するように思われる場合は、shared_ptrのコンテナを使用し、Bをweak_ptrとします。性能面での不利な点があります。

+1

Ya、私は、ポインタの所有権がAであるため、Bはポインタを持つべきではなく、pctr内の要素への参照であるため、設計の背後にある論理的根拠はそうであると思われる。言い換えれば、Bの宣言は、pctr内の要素が常に存在するという事実に基づいていなければならない。 –

+0

構文的な砂糖であるにもかかわらず、 'reference_wrapper'は医師が処方したものだけかもしれません。 http://stackoverflow.com/questions/193703/how-is-tr1referencewrapper-useful –