[解決済み】スマートポインタ(boost)の説明
質問
次のポインターのセットは何が違うのでしょうか?それぞれのポインターをプロダクションコードで使用するとしたら、どのような場合ですか?
例を挙げていただけるとありがたいです。
-
scoped_ptr
-
shared_ptr
-
weak_ptr
-
intrusive_ptr
プロダクションコードでboostを使用していますか?
どのように解決するのですか?
スマートポインタの基本特性
各スマートポインタに割り当てるプロパティがあれば、簡単です。重要なプロパティは3つあります。
- 所有権なし
- 所有権移転
- 所有権分担
1つ目の意味は、スマートポインターはオブジェクトを所有していないため、オブジェクトを削除できないことです。2つ目は、スマートポインタは同時に1つしか同じオブジェクトを指すことができないことを意味します。スマートポインタが関数から返される場合、所有権は返されたスマートポインタに移される、といった具合です。
3つ目は、複数のスマートポインタが同時に同じオブジェクトを指すことができることを意味します。これは ローポインター しかし、生ポインターには重要な特徴がありません。それは 所有 を使うかどうかです。所有権共有型スマートポインタは、すべての所有者がオブジェクトを手放した場合、そのオブジェクトを削除します。この動作はたまたま頻繁に必要になるため、所有権共有型スマートポインタは広く普及しています。
いくつかの所有型スマートポインタは、2番目と3番目のどちらもサポートしていません。そのため、関数から返したり、どこかに渡したりすることができません。どちらが最も適しているかというと
RAII
スマートポインタがローカルに保持され、オブジェクトがスコープ外に出た後に解放されるように作成されるだけである場合。
所有権の共有は、コピーコンストラクタを持つことで実装できます。これは当然スマートポインタをコピーし、コピーとオリジナルの両方が同じオブジェクトを参照することになります。C++では、あるオブジェクトから別のオブジェクトに何かを転送する手段がサポートされていないため、所有権の移転は現在のところ実際に実装することはできません。関数からオブジェクトを返そうとすると、そのオブジェクトはコピーされてしまいます。つまり、所有権の移動を実装したスマートポインタは、その所有権の移動を実装するためにコピーコンストラクタを使用しなければならないのです。なぜなら、コンテナの要素のコピーコンストラクタの動作は、スマートポインタのいわゆる「移動コンストラクタ」の動作と互換性がないからです。
C++1x では、いわゆる "move コンストラクタおよび "move 代入演算子を導入することにより、所有権移動のネイティブ サポートが提供されます。また、このような所有権移動スマート ポインターは
unique_ptr
.
スマートポインタの分類
scoped_ptr
は、転送も共有もできないスマートポインタです。局所的にメモリを確保する必要がある場合にのみ使用可能ですが、スコープ外に出た場合は必ず再度解放するようにしてください。しかし、他の scoped_ptr とスワップしたい場合は、スワップすることができます。
shared_ptr
は所有権を共有するスマートポインタです(上記3種類目)。参照カウントされるので、最後のコピーがスコープ外に出たときに、管理されているオブジェクトを解放することができます。
weak_ptr
は非所有型スマートポインタです。これは、(shared_ptrによって管理されている)管理対象オブジェクトを参照カウントを追加せずに参照するために使用されます。通常、shared_ptrから生のポインタを取り出して、それをコピーする必要があります。しかし、それでは、オブジェクトが実際に削除されたときに確認する方法がないため、安全ではありません。そこで weak_ptr は shared_ptr が管理するオブジェクトを参照することで、その手段を提供します。もし、そのオブジェクトにアクセスする必要があれば、そのオブジェクトの管理をロックし(そのオブジェクトを使用している間に他のスレッドで shared_ptr がそれを解放することを避けるため)、それから使用することができます。weak_ptr が既に削除されたオブジェクトを指している場合は、例外を投げて通知します。weak_ptr の使用は、循環的な参照がある場合に最も有益です。参照カウントはこのような状況に容易に対応することができません。
intrusive_ptr
はshared_ptrのようなものですが、参照カウントをshared_ptrに保持せず、カウントの増減は管理対象のオブジェクトが定義する必要があるいくつかのヘルパー関数に任せます。これは、すでに参照されているオブジェクト(外部の参照カウント機構によって参照カウントが増加する)をintrusive_ptrに詰め込むことができるという利点があります - 参照カウントはもうスマートポインタの内部ではなく、スマートポインタは既存の参照カウント機構を使用するためです。
unique_ptr
は所有権移転ポインタです。コピーすることはできませんが、C++1x の移動コンストラクタを使用することで移動させることができます。
unique_ptr<type> p(new type);
unique_ptr<type> q(p); // not legal!
unique_ptr<type> r(move(p)); // legal. p is now empty, but r owns the object
unique_ptr<type> s(function_returning_a_unique_ptr()); // legal!
これは,std::auto_ptr が従うセマンティックですが,移動のネイティブサポートが欠落しているため,落とし穴なしにそれらを提供することができません.C++1x では、移動のみ可能でコピー不可能なオブジェクトをコンテナに格納することも可能になります。つまり、例えばvectorの中にunique_ptrを詰め込むことができるわけです。ここでやめて、以下を参照することにする。 いい記事 これについては、もっと詳しく知りたい方は、こちらをご覧ください。
関連
-
[解決済み】関数名の前に期待されるイニシャライザー
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】指定範囲内の乱数で配列を埋める(C++)
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] const int*、const int * const、int const *の違いは何ですか?
-
[解決済み] リファレンスとポインタの使い分け
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] テスト
-
[解決済み】コンストラクターでのエラー:識別子を期待されますか?
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み] [Solved] インクルードファイルが開けません。'stdio.h' - Visual Studio Community 2017 - C++ Error
-
[解決済み】なぜ、サイズ8の初期化されていない値を使用するのでしょうか?
-
[解決済み】std::cin.getline( ) vs. std::cin
-
[解決済み] 変数サイズのオブジェクトが初期化されないことがある c++
-
[解決済み] "std::bad_alloc": 私はメモリを使いすぎているのでしょうか?
-
[解決済み】unique_ptrとshared_ptrの違い【重複あり