1. ホーム
  2. c++

[解決済み] ポインタ、スマートポインタ、共有ポインタ?重複

2022-08-14 18:03:49

質問

私は通常のポインタでプログラミングをしていますが、Boostのようなスマートポインタを実装したライブラリがあることを知りました。また、Ogre3Dのレンダリングエンジンでは、共有ポインタを深く利用しているのを見たことがあります。

この3つの違いは一体何なのでしょうか?

どのように解決するのですか?

シディウスは、その種類をかなりよく説明してくれました。

  • 通常のポインタ はまさにそれです - メモリ上のどこかのものを指しています。誰がそれを所有しているのでしょうか?コメントで知ることができます。誰がそれを解放するのですか?うまくいけば、ある時点で所有者になります。
  • スマートポインタ は多くの型をカバーする包括的な用語です。 RAII パターンを使用するスコープ付きポインタのことだと思われます。これは、ポインタをラップするスタックアロケートされたオブジェクトで、それがスコープ外に出たとき、ラップしているポインタに対して delete を呼び出します。これは、含まれるポインタを所有し、ある時点でそれを削除することを担当します。ラップしたポインタを他のメソッドに渡すために、ラップしたポインタの生の参照を取得することができます。 解放する を解放し、他の誰かがポインタを所有することを可能にします。それらをコピーすることは意味を持ちません。
  • 共有ポインタ は、スタックに割り当てられたオブジェクトで、ポインタをラップして、誰が所有しているかを知る必要がないようにします。メモリ内のオブジェクトに対する最後の共有ポインタが破壊されると、ラップされたポインタも削除されます。

どのような場合に使うべきでしょうか。スコープ付きポインタと共有ポインタのどちらかを多用することになります。アプリケーションで実行されているスレッドはいくつありますか? もし答えが「たくさんある」なら、共有ポインターはどこでも使えるパフォーマンスのボトルネックになる可能性があります。なぜなら、共有ポインタの作成/コピー/破棄はアトミックな操作である必要があり、多くのスレッドが実行されている場合、これはパフォーマンスの妨げになる可能性があるからです。しかし、常にそうなるとは限りません。確かなことは、テストしてみなければわかりません。

共有ポインターを使用することによって、プログラマーが誰がポインターを所有しているかを無視することを許可することになります。これは、循環参照 (Java はこれらを検出しますが、共有ポインターは検出できません) や大規模なコード ベースにおける一般的なプログラマーの怠惰で厄介な状況をもたらす可能性があります。

スコープ付きポインターを使用する理由は2つあります。1 つ目は、単純な例外安全性とクリーンアップ操作のためです。例外に直面したときに何があってもオブジェクトがクリーンアップされることを保証したい場合、そしてそのオブジェクトをスタックアロケートしたくない場合、それをスコープ付きポインターに置きます。操作が成功したら、それを共有ポインタに自由に移行できますが、その間、スコープ付きポインタでオーバーヘッドを節約します。

もうひとつのケースは、明確なオブジェクトの所有権を得たい場合です。これを好むチームもあれば、そうでないチームもあります。例えば、データ構造は内部オブジェクトへのポインタを返すかもしれません。スコープ付きポインタの場合、それは弱い参照として扱われるべき生のポインタまたは参照を返すでしょう - それを所有するデータ構造が破壊された後にそのポインタにアクセスすることはエラーであり、それを削除することもエラーです。共有ポインターの下では、誰かがまだハンドルを保持している場合、所有するオブジェクトはそれが返した内部データを破棄することができません - これは必要以上に長い間リソースを開いたままにするか、コードによってははるかに悪化する可能性があります。