C ++ 03
std::auto_ptr
-おそらく、最初のドラフトシンドロームの影響を受けたオリジナルの1つだけが、限られたガベージコレクション機能しか提供していません。最初の欠点はdelete
、破棄が必要になるため、配列に割り当てられたオブジェクト(new[]
)を保持することができないことです。ポインターの所有権を取得するため、2つの自動ポインターに同じオブジェクトを含めることはできません。割り当ては所有権を転送し、右辺値自動ポインタをnullポインタにリセットします。これはおそらく最悪の欠点につながります。前述のコピーができないため、STLコンテナ内では使用できません。ユースケースに対する最後の打撃は、C ++の次の標準で非推奨になる予定です。
std::auto_ptr_ref
-これはスマートポインターではなく、std::auto_ptr
特定の状況でのコピーと割り当てを可能にするために実際に使用されるデザインの詳細です。具体的には、移動コンストラクターとしても知られるColvin-Gibbonsトリックを使用して、非const std::auto_ptr
を左辺値に変換し、所有権を転送するために使用できます。
それどころかstd::auto_ptr
、自動ガベージコレクション用の汎用スマートポインタとして使用することは、実際には意図されていなかったのでしょう。私の限られた理解と仮定のほとんどは、Herb Sutterのauto_ptrの効果的な使用に基づいており、常に最適化されているわけではありませんが、定期的に使用しています。
C ++ 11
std::unique_ptr
-これは、配列std::auto_ptr
を操作するstd::auto_ptr
ような弱点、プライベートコピーコンストラクターによる左辺値保護、STLコンテナーやアルゴリズムで使用できるなどの弱点を修正するための重要な改善を除いて、非常に似ています。メモリーフットプリントが限られているため、これは、生のポインターを置き換える、または所有者として適切に説明されている生のポインターの理想的な候補です。「一意」が意味するのは、前述のようにポインタの所有者が1人だけであること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
-私はこれを使用したことがありませんが、私の理解から、独自のスマートポインター互換クラスを作成するときに使用するように設計されています。参照カウントを自分で実装する必要があります。クラスをジェネリックにする場合は、いくつかのメソッドも実装する必要があります。さらに、独自のスレッドセーフを実装する必要があります。プラスの面では、これはおそらく、どれだけ多くの、またはどれだけ小さな「スマートさ」が必要かを正確に選択する最もカスタムな方法を提供します。オブジェクトごとに1つのヒープを割り当てることができるため、intrusive_ptr
通常より効率的ですshared_ptr
。(Arvidに感謝)
boost::shared_array
-これはboost::shared_ptr
配列用です。基本的にnew []
、operator[]
、もちろんdelete []
で焼かれています。これは、STLコンテナで使用され、私の知る限りでは、すべてが行うことができboost:shared_ptr
、使用することはできませんが、ないboost::weak_ptr
これらと。ただし、代わり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
およびderef
いますが、サブクラス化によって実行できる)をですQSharedData
。多くのQtと同様に、オブジェクトは十分な継承とサブクラス化を通じて最適に使用され、すべてが意図された設計のようです。
QExplicitlySharedDataPointer
-をQSharedDataPointer
暗黙的に呼び出さないことを除いて、非常に似ていますdetach()
。私はこのバージョン2.0をQSharedDataPointer
、参照カウントがゼロに落ちた後、いつデタッチするかについての制御のわずかな増加は、まったく新しいオブジェクトに特に価値がないので、ます。
QSharedPointer
-原子参照カウント、スレッドセーフ、共有可能なポインター、カスタム削除(配列のサポート)は、スマートポインターのすべてのように聞こえます。これは主にQtでスマートポインターとして使用するものであり、boost:shared_ptr
あり、Qtの多くのオブジェクトのようにおそらくはるかに多くのオーバーヘッドますが、
QWeakPointer
-再発パターンを感じますか?同様にstd::weak_ptr
、boost::weak_ptr
これはQSharedPointer
、オブジェクトが削除されない2つのスマートポインター間の参照が必要な場合に使用されます。
QScopedPointer
-この名前も見慣れたものに見えるはずであり、実際にboost::scoped_ptr
はQtバージョンの共有ポインターとウィークポインターとは異なります。それはのオーバーヘッドなしに、単一の所有者のスマートポインタを提供するために、機能QSharedPointer
の互換性、例外安全なコード、そしてあなたが使用する可能性のあるすべてのもののためにそれがより適しているstd::auto_ptr
かboost::scoped_ptr
について。