ポインタ、スマートポインタ、それとも共有ポインタ? [重複] 質問する

ポインタ、スマートポインタ、それとも共有ポインタ? [重複] 質問する

私は通常のポインターを使用してプログラミングしていますが、スマート ポインターを実装する Boost などのライブラリについて聞いたことがあります。また、Ogre3D レンダリング エンジンでは共有ポインターが多用されていることもわかりました。

これら 3 つの違いは正確には何ですか? また、そのうちの 1 種類だけを使用するべきですか?

ベストアンサー1

Sydius はタイプをかなりわかりやすく概説しました。

  • 通常のポインタそれらは、メモリ内のどこかにあるものを指します。誰がそれを所有しているか? コメントだけがそれを知ることができます。誰がそれを解放するか? できれば、ある時点で所有者が解放します。
  • スマートポインタ多くの型をカバーする包括的な用語です。スコープ付きポインターを意味していると仮定します。RAIIパターン。これはポインタをラップするスタック割り当てオブジェクトです。スコープ外になると、ラップしているポインタの削除を呼び出します。これは、含まれているポインタを「所有」し、ある時点で削除する責任を負います。これにより、ラップしているポインタへの生の参照を取得して他のメソッドに渡すことができます。解放するポインターをコピーして、他のユーザーが所有できるようにします。コピーしても意味がありません。
  • 共有ポインタは、ポインタをラップするスタック割り当てオブジェクトなので、所有者を意識する必要はありません。メモリ内のオブジェクトの最後の共有ポインタが破棄されると、ラップされたポインタも削除されます。

では、いつ使用すべきでしょうか? スコープ ポインターまたは共有ポインターを頻繁に使用することになります。アプリケーションでは、いくつのスレッドが実行されていますか? 答えが「潜在的に多数」である場合、共有ポインターをあらゆる場所で使用した場合、パフォーマンスのボトルネックになる可能性があります。その理由は、共有ポインターの作成、コピー、破棄はアトミック操作である必要があり、多数のスレッドが実行されている場合、パフォーマンスが低下する可能性があるためです。ただし、常にそうであるとは限りません。確実にわかるのはテストだけです。

共有ポインターに反対する議論 (私も賛成です) があります。共有ポインターを使用すると、プログラマーはポインターの所有者を無視できるようになります。これにより、循環参照 (Java はこれを検出しますが、共有ポインターは検出できません) や大規模なコード ベースでの一般的なプログラマーの怠慢といった厄介な状況が発生する可能性があります。

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

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

おすすめ記事