web-dev-qa-db-ja.com

std :: vectorのようなコンテナ内のスマートポインタ?

私はスマートポインタについて学んでいます(std::auto_ptr)そして ここここ そのスマートポインタ(std::auto_ptr)コンテナに入れてはいけません(つまり、std::vector)ほとんどのコンパイラでさえ文句を言わず、正しいように見えるかもしれないからです。スマートポインタが内部的に(たとえばvectorクラスによって)コピーされてその所有権を譲渡しないという規則はありません。そうすると、ポインタはNULLになります。結局、すべてが台無しになります。

実際には、これはどのくらいの頻度で発生しますか?

時々私はポインターのベクトルを持っています、そして将来私がスマートポインターのベクトルを持ちたいと思ったら私のオプションは何でしょうか?

私はC++ 0xとBoostライブラリを知っていますが、今のところ、STLアプローチに固執したいと思います。

19
nacho4d

はい、あなた本当には標準のコンテナでstd::auto_ptrを使用できません。 std::auto_ptrコピーは同等ではありません。また、標準のコンテナー(およびアルゴリズム)は要素を自由にコピーできるため、これは問題を引き起こします。つまり、std::auto_ptrをコピーする操作には、オブジェクトの単なるコピー以外の意味otherがあります。つまり、所有権の譲渡

オプションは次のとおりです。

  1. Boost Smart Pointersライブラリ を使用します。これは間違いなくあなたの最良の選択肢です。
  2. プリミティブポインタを使用します。ポインタを適切に管理している限り、これは高速で安全です。時には、これは複雑または困難な場合があります。たとえば、二重削除の問題に自分で対処(回避)する必要があります。
  3. 独自の参照カウントスマートポインタを使用してください。それはばかげているでしょう。 Boostスマートポインタを使用します。
16
wilhelmtell

あなたが言及している問題は、auto_ptrがコピーの所有権を移動するためです。 shared_ptrとunique_ptrは、コンテナーで問題なく機能します。

9
ronag

標準のコンテナテンプレートで使用するタイプは、そのコンテナの要件に準拠している必要があります。特に、タイプはCopyConstructibleおよびAssignableタイプの要件を満たしている必要があります。

多くのスマートポインタはこれらの要件を満たし、標準のコンテナで使用できますが、std::auto_ptrのコピーは作成または割り当てられたソースと同等ではないため、std::auto_ptrはその1つではありません。

標準コンテナの一部の実装はauto_ptrで機能する場合がありますが、そのような実装の詳細に依存することは危険です。

3
CB Bailey

理論的には、STLコンテナーの内部実装を完全に理解し、auto_ptrの所有権を失う可能性のあることを何もしなければ、std::auto_ptrをSTLコンテナーで使用できますが、実際には、生のptrでコンテナーを使用する方がはるかに安全です。

「実際、これはどのくらいの頻度で発生しますか?」 -それ自体が非常に危険な質問です。まず第一に、STL-それは単一の標準実装ではなく、たくさんあります。それぞれが異なる方法でコンテナーを実装できるため、すべての「コンテナー内のauto_ptr」マインを回避するように高度に調整されたコードは、別のSTL実装への切り替えをバーストする可能性があります。また、コードのメンテナンスは非常に複雑になり、コードに正しく見える変更を加えると、プログラムが破損する可能性があります。どうすればそれを覚えたり、他のメンテナに覚えさせたりできますか?そのような変更が発生する可能性のある場所に警告を配置しますか?不可能な。

つまり、結論:頭痛だけをもたらすのは悪い考えです

2
Andriy Tylychko

自動ptrデータメンバーを持つクラスの場合、常に新しい自動ptrを返すクローンメソッドがあります。次に、cloneメソッドを呼び出す代入メソッドとコピーコンストラクターを実装します(auto ptrのデフォルトの代入演算子は決してありません)。このようにして、STLコンテナでクラスを安全に使用できます。

1
sbalian