[解決済み] ポインタ、スマートポインタ、共有ポインタ?重複
質問
私は通常のポインタでプログラミングをしていますが、Boostのようなスマートポインタを実装したライブラリがあることを知りました。また、Ogre3Dのレンダリングエンジンでは、共有ポインタを深く利用しているのを見たことがあります。
この3つの違いは一体何なのでしょうか?
どのように解決するのですか?
シディウスは、その種類をかなりよく説明してくれました。
- 通常のポインタ はまさにそれです - メモリ上のどこかのものを指しています。誰がそれを所有しているのでしょうか?コメントで知ることができます。誰がそれを解放するのですか?うまくいけば、ある時点で所有者になります。
- スマートポインタ は多くの型をカバーする包括的な用語です。 RAII パターンを使用するスコープ付きポインタのことだと思われます。これは、ポインタをラップするスタックアロケートされたオブジェクトで、それがスコープ外に出たとき、ラップしているポインタに対して delete を呼び出します。これは、含まれるポインタを所有し、ある時点でそれを削除することを担当します。ラップしたポインタを他のメソッドに渡すために、ラップしたポインタの生の参照を取得することができます。 解放する を解放し、他の誰かがポインタを所有することを可能にします。それらをコピーすることは意味を持ちません。
- 共有ポインタ は、スタックに割り当てられたオブジェクトで、ポインタをラップして、誰が所有しているかを知る必要がないようにします。メモリ内のオブジェクトに対する最後の共有ポインタが破壊されると、ラップされたポインタも削除されます。
どのような場合に使うべきでしょうか。スコープ付きポインタと共有ポインタのどちらかを多用することになります。アプリケーションで実行されているスレッドはいくつありますか? もし答えが「たくさんある」なら、共有ポインターはどこでも使えるパフォーマンスのボトルネックになる可能性があります。なぜなら、共有ポインタの作成/コピー/破棄はアトミックな操作である必要があり、多くのスレッドが実行されている場合、これはパフォーマンスの妨げになる可能性があるからです。しかし、常にそうなるとは限りません。確かなことは、テストしてみなければわかりません。
共有ポインターを使用することによって、プログラマーが誰がポインターを所有しているかを無視することを許可することになります。これは、循環参照 (Java はこれらを検出しますが、共有ポインターは検出できません) や大規模なコード ベースにおける一般的なプログラマーの怠惰で厄介な状況をもたらす可能性があります。
スコープ付きポインターを使用する理由は2つあります。1 つ目は、単純な例外安全性とクリーンアップ操作のためです。例外に直面したときに何があってもオブジェクトがクリーンアップされることを保証したい場合、そしてそのオブジェクトをスタックアロケートしたくない場合、それをスコープ付きポインターに置きます。操作が成功したら、それを共有ポインタに自由に移行できますが、その間、スコープ付きポインタでオーバーヘッドを節約します。
もうひとつのケースは、明確なオブジェクトの所有権を得たい場合です。これを好むチームもあれば、そうでないチームもあります。例えば、データ構造は内部オブジェクトへのポインタを返すかもしれません。スコープ付きポインタの場合、それは弱い参照として扱われるべき生のポインタまたは参照を返すでしょう - それを所有するデータ構造が破壊された後にそのポインタにアクセスすることはエラーであり、それを削除することもエラーです。共有ポインターの下では、誰かがまだハンドルを保持している場合、所有するオブジェクトはそれが返した内部データを破棄することができません - これは必要以上に長い間リソースを開いたままにするか、コードによってははるかに悪化する可能性があります。
関連
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】変数 '' を抽象型 '' と宣言できない。
-
[解決済み] 既に.objで定義されている-二重包含はない
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み] to_string は std のメンバーではない、と g++ が言っている (mingw)
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] C++の参照変数を返す習慣は悪なのか?
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
-
[解決済み】共有オブジェクト(.so)、静的ライブラリ(.a)、DLL(.so)の違い?)
-
[解決済み] なぜC++のライブラリやフレームワークではスマートポインタが使われないのですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】LLVMで暗黙のうちに削除されたコピーコンストラクタの呼び出し
-
[解決済み】非静的メンバ関数への参照を呼び出す必要がある
-
[解決済み】C++エラーです。"配列は中括弧で囲まれたイニシャライザーで初期化する必要がある"
-
[解決済み】C++でランダムな2倍数を生成する
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み】なぜ、サイズ8の初期化されていない値を使用するのでしょうか?
-
[解決済み】Visual Studioのデバッガーエラー。プログラムを開始できません 指定されたファイルが見つかりません
-
[解決済み】'std::cout'への未定義の参照
-
[解決済み] スマートポインターとは何ですか?