2013-04-22 8 views
7

私が理解する限り、stuffがvectorにpushed_backされているときに、新しいメモリブロックを割り当てなければならない場合があります。その結果、すべての要素が古いメモリブロックからコピーされ、デストラクタが呼び出されます。 unique_ptrデストラクタは所有メモリを削除するので、vectorでどのように動作する可能性がありますか? unique_ptrをベクトルで使用するのは安全ですか? 通常のポインタよりも遅いですか?ベクトル<unique_ptr> push_backでリサイズ - どのように動作しますか?

答えて

12

この結果、すべての要素が古いメモリブロックからコピーされ、デストラクタが呼び出されます。 unique_ptrデストラクタは所有メモリを削除するので、vectorでどのように動作する可能性がありますか?

は実際に、それはより多くの任意のない厳密コピー要素だ、それは移動です。暗黙または明示的な移動コンストラクタを持たない型については、それは同じです。しかし、unique_ptrの場合、新しい「unique_ptr」は、「old」unique_ptrのrvalue-referenceを指定すると、新しく割り当てられたメモリに構築されます。その移動コンストラクタは適切な処理を行います。つまり、所有者を古いものから新しいものに変更します。unique_ptrは古いものを空のままにしておくため、破棄されると何も削除されません。

vectorでunique_ptrを使用するのは安全ですか?

それは限り、あなたは言語規則および「C++常識」を尊重するとして、どこでもunique_ptrを使用することを保存します。つまり、あなたはを明示的ににしなければならないでしょう。unique_ptrの安全な動作を壊すために愚かなことをしてください。それらの中には、例えば、さらに別のスマートポインタを所有しているオブジェクトの所有権を与えることをふり:

unique_ptr<T> ptr1 {new T()}; 
unique_ptr<T> ptr2 {ptr1.get()}; //two unique_ptr's owning the same object... 

またはC++オブジェクトの寿命を尊重しないreinterpret_castmemcpymemsetまたは他のものを含むいくつかの破壊アクション。

通常のポインタよりも遅いですか?

多分。 unique_ptrを生ポインタをコピーする、すなわちオリジナルをゼロに設定するのと比較して移動するときには、若干のオーバーヘッドがはっきりしています。しかし、オーバーヘッドを最適化するかどうかは、コンパイラとオプティマイザによって異なります。パフォーマンスがこれまでどおり、プロファイラと相談して、であるかどうか、そして減速が問題かどうかを判断してください。私はそうではないと賭けて、スマートポインタがあなたに与えるセキュリティの量を考慮に入れて、ちょうどunique_ptrの性能について尋ねることはありません。

サイドノート:ベクターのサイズを事前に知っている場合は、vector::reserve()を使用してください。それはunique_ptrの再割り当てと移動を保存します。ベクトルが持つおおよそのサイズだけを知っていれば、軽微ではありません。unique_ptrはあまり大きくありません(通常、生のポインタとdeleterの大きさは最適化されているかもしれません)。メモリの制約が厳しい場合を除いて、数%以上は傷つけません。

+0

*あなたが本当に厳しい記憶の制約がないかぎり、百以上を確保することは痛いことではありません。* =>まあ、コンテナが十数ほどの要素に使用されていることを考えると、 ; 10%増のように。 –

+0

@MatthieuM。フィードバックいただきありがとうございます、私はその部分を改めました。 –

+0

@Arne:vector <>コンテナでunique_ptr <>を使用できるのであれば、なぜauto_ptr <>ですか? afterall auto_ptr <>は、オブジェクトの責任を新しいオブジェクトに移します。したがって、auto_ptr <>を使用することは、その意味でも安全でなければなりません。しかし、私はそれが事実ではないと信じていますか? – David

3

cppreferenceによれば、std::unique_ptrのユースケースの1つは、std::vectorのような「移動対応コンテナ」で使用されています。これは、がが可動であるときに検出するのに十分スマートであることを意味し、std::unique_ptrの場合であり、ベクトルのサイズを変更するときには移動コンストラクタを使用します。

6

移動セマンティクスでは、ある場所から別の場所にunique_ptrを移動することができます。これにより、ポインタが保持するデータが破壊されるのを防ぐことができます。std::moveを使用して1つのメモリ位置から別のメモリ位置に「移動」します。

これは、ベクトルが大きくなると、古いベクトル配列から新しいメモリ位置への浅いコピーのようなものです。

+0

@RandyGual Afterall auto_ptr <>は、セグメンテーションの移動もサポートしており、オブジェクトの責任を新しいオブジェクトに移します。したがって、auto_ptr <>を使用することは、その意味でも安全でなければなりません。しかし、私はそれが事実ではないと信じていますか? – David

関連する問題