C ++ 03
std::auto_ptr
-おそらく、最初のドラフト症候群に苦しんでいたオリジナルの1つは、限られたガベージコレクション施設しか提供していませんでした。最初の欠点はdelete
、破壊を要求するため、配列に割り当てられたオブジェクトを保持できないことです(new[]
)。ポインタの所有権を取得するため、2つの自動ポインタに同じオブジェクトが含まれることはありません。割り当てにより、所有権が譲渡され、右辺値の自動ポインターがnullポインターにリセットされます。これはおそらく最悪の欠点につながります。前述のコピーができないため、STLコンテナ内では使用できません。ユースケースの最後の打撃は、C++の次の標準で非推奨になる予定です。
std::auto_ptr_ref
std::auto_ptr
-これはスマートポインタではなく、実際には、特定の状況でコピーと割り当てを可能にするために組み合わせて使用される設計の詳細です。具体的には、所有権を譲渡するための移動コンストラクターとしても知られるColvin-Gibbonsトリックを使用して、非定数std::auto_ptr
を左辺値に変換するために使用できます。
それどころかstd::auto_ptr
、自動ガベージコレクションの汎用スマートポインタとして使用することを意図したものではなかったのかもしれません。私の限られた理解と仮定のほとんどは、ハーブサッターのauto_ptrの効果的な使用に基づいており、常に最適化された方法であるとは限りませんが、定期的に使用しています。
C ++ 11
std::unique_ptr
-これは私たちの友人であり、配列の操作、プライベートコピーコンストラクターによる左辺値の保護、STLコンテナーやアルゴリズムでの使用などstd::auto_ptr
の弱点を修正するための主要な改善点を除いて、非常によく似ています。パフォーマンスのオーバーヘッドであるためメモリーフットプリントは限られています。これは、生のポインターを置き換える、またはおそらくより適切に所有していると説明するための理想的な候補です。「一意」とは、前のポインタと同じように、ポインタの所有者が1人だけであることを意味します。std::auto_ptr
std::auto_ptr
std::shared_ptr
-これはTR1に基づいていると思いますboost::shared_ptr
が、エイリアシングとポインタ演算も含めるように改善されています。つまり、動的に割り当てられたオブジェクトの周りに参照カウントされたスマートポインターをラップします。「共有」は、最後の共有ポインターの最後の参照がスコープ外になると、ポインターが複数の共有ポインターによって所有される可能性があることを意味するため、オブジェクトは適切に削除されます。これらもスレッドセーフであり、ほとんどの場合、不完全な型を処理できます。デフォルトのアロケータを使用して、1つのヒープ割り当てでstd::make_shared
効率的にを構築するために使用できます。std::shared_ptr
std::weak_ptr
-同様にTR1とに基づいていboost::weak_ptr
ます。これは、が所有するオブジェクトへの参照であるため、参照数がゼロstd::shared_ptr
になってもオブジェクトの削除を妨げることはありません。std::shared_ptr
生のポインタにアクセスするには、最初にstd::shared_ptr
を呼び出すことによってアクセスする必要があります。これは、所有されているポインタの有効期限が切れてすでに破棄されている場合はlock
空を返します。std::shared_ptr
これは主に、複数のスマートポインターを使用するときに、参照カウントが無期限にハングするのを防ぐのに役立ちます。
ブースト
boost::shared_ptr
-おそらく、最も多様なシナリオ(STL、PIMPL、RAIIなど)で使用するのが最も簡単です。これは、共有参照されたカウントされたスマートポインターです。いくつかの状況でパフォーマンスとオーバーヘッドについていくつかの不満を聞いたことがありますが、議論が何であったかを思い出せないので、それらを無視したに違いありません。どうやらそれは保留中の標準C++オブジェクトになるのに十分人気があり、スマートポインタに関する標準を超える欠点は思い浮かびません。
boost::weak_ptr
-の前の説明と同様std::weak_ptr
に、この実装に基づいて、これにより、を所有していない参照が可能になりますboost::shared_ptr
。当然のことながら、「強力な」共有ポインタにアクセスするために呼び出しlock()
、すでに破棄されている可能性があるため、有効であることを確認する必要があります。返された共有ポインタを保存しないように注意し、使い終わったらすぐにスコープから外してください。そうしないと、参照カウントがハングし、オブジェクトが破棄されない循環参照の問題に戻ります。
boost::scoped_ptr
-これは、オーバーヘッドがほとんどない単純なスマートポインタークラスであり、おそらくboost::shared_ptr
使用可能な場合よりもパフォーマンスが向上するように設計されています。std::auto_ptr
これは、STLコンテナの要素として、または同じオブジェクトへの複数のポインタで安全に使用できないという事実に特に匹敵します。
boost::intrusive_ptr
-私はこれを使用したことがありませんが、私の理解から、独自のスマートポインタ互換クラスを作成するときに使用するように設計されています。自分でカウントする参照を実装する必要があります。クラスを汎用にする場合は、いくつかのメソッドも実装する必要があります。さらに、独自のスレッドセーフを実装する必要があります。プラス面としては、これにより、必要な「スマートさ」を正確にどれだけ、またはどれだけ少なくするかを選択するための最もカスタムな方法が得られるでしょう。通常、オブジェクトごとに単一のヒープ割り当てを行うことができるためintrusive_ptr
、より効率的です。(Arvidに感謝)shared_ptr
boost::shared_array
-これはboost::shared_ptr
アレイ用です。基本的new []
に、、、operator[]
およびもちろんdelete []
ベイクインされます。これはSTLコンテナーで使用でき、私が知る限り、これらでboost:shared_ptr
は使用できませんが、すべてが実行されますboost::weak_ptr
。ただし、代わりにaを使用しboost::shared_ptr<std::vector<>>
て同様の機能を使用boost::weak_ptr
し、参照に使用する機能を取り戻すこともできます。
boost::scoped_array
-これはboost::scoped_ptr
アレイ用です。必要なすべてのアレイと同様にboost::shared_array
、優れた機能が組み込まれています。これはコピーできないため、STLコンテナでは使用できません。私はあなたがこれを使いたいと思うほとんどどこでもあなたがたぶん使うことができるのを見つけましたstd::vector
。どちらが実際に高速であるか、オーバーヘッドが少ないかを判断したことはありませんが、このスコープ配列はSTLベクトルよりもはるかに複雑ではないようです。スタックに割り当てを保持したい場合は、boost::array
代わりに検討してください。
Qt
QPointer
-Qt 4.0で導入された、これは「弱い」スマートポインターでありQObject
、クラスと派生クラスでのみ機能します。Qtフレームワークではほとんどすべてであるため、実際には制限はありません。ただし、「強力な」ポインタを提供しないという制限があります。基になるオブジェクトが有効かどうかを確認isNull()
できますが、特にマルチスレッド環境では、そのチェックに合格した直後にオブジェクトが破棄される可能性があります。Qtの人々は、これは非推奨だと私は信じています。
QSharedDataPointer
boost::intrusive_ptr
-これは、スレッドセーフが組み込まれているものの、潜在的に同等の「強力な」スマートポインターですが、サブクラス化によって実行できる参照カウントメソッド(ref
および)を含める必要があります。Qtの多くと同様に、オブジェクトは十分な継承を通じて最もよく使用され、すべてをサブクラス化することは意図された設計のようです。deref
QSharedData
QExplicitlySharedDataPointer
QSharedDataPointer
-暗黙的にを呼び出さないことを除いて、非常に似ていますdetach()
。QSharedDataPointer
参照カウントがゼロに低下した後、いつデタッチするかについての制御のわずかな増加は、まったく新しいオブジェクトの価値が特にないため、このバージョン2.0と呼びます。
QSharedPointer
-アトミック参照カウント、スレッドセーフ、共有可能なポインター、カスタム削除(配列サポート)、スマートポインターが必要なすべてのように聞こえます。これは、私が主にQtのスマートポインターとして使用するものでboost:shared_ptr
あり、Qtの多くのオブジェクトのように、おそらく大幅にオーバーヘッドが大きくなりますが、それに匹敵すると思います。
QWeakPointer
-繰り返し発生するパターンを感じますか?同様にstd::weak_ptr
、これは、オブジェクトが削除されない原因となる2つのスマートポインター間の参照が必要な場合boost::weak_ptr
と組み合わせて使用されます。QSharedPointer
QScopedPointer
-この名前も見覚えがあるはずですが、実際にboost::scoped_ptr
は、Qtバージョンの共有ポインターや弱ポインターとは異なります。これは、オーバーヘッドなしで単一の所有者のスマートポインターを提供するように機能し、QSharedPointer
互換性、例外安全コード、および使用する可能性のあるすべてのものに適していstd::auto_ptr
ますboost::scoped_ptr
。