間違った質問
スマート ポインターを使用する C++ プロジェクトの場合
この問題は、実際にはスマート ポインターとは何の関係もありません。それは所有権についてのみです。
スマートポインターは単なるツールです
彼らは所有権の概念、特にWRTを何も変えません。プログラムで明確に定義された所有権を持つ必要性、所有権は自発的に譲渡できますが、クライアントが取得することはできないという事実。
スマート ポインター (ロックやその他の RAII オブジェクトも) は、値と、この値を WRT する関係を同時に表すことを理解する必要があります。Ashared_ptr
はオブジェクトへの参照であり、関係を確立します。オブジェクトは、 thisshared_ptr
の前に破棄されてはなりません。また、 thisshared_ptr
が破棄されたときに、これがこのオブジェクトの最後のエイリアスである場合、オブジェクトはすぐに破棄されなければなりません。(は、定義によりエイリアシングがゼロunique_ptr
の特殊なケースと見なすことができるため、は常にオブジェクトのエイリアシングの最後のものです。)shared_ptr
unique_ptr
スマート ポインターを使用する理由
変数や関数の宣言だけで多くのことを表現するため、スマート ポインターを使用することをお勧めします。
スマート ポインターは、明確に定義された設計のみを表現できます。所有権を定義する必要がなくなるわけではありません。対照的に、ガベージ コレクションでは、メモリの割り当て解除の責任者を定義する必要がなくなります。(ただし、他のリソースのクリーンアップの責任者を定義する必要性を取り除かないでください。)
ガベージ コレクションが純粋に機能しない言語であっても、所有権を明確にする必要があります。他のコンポーネントがまだ古い値を必要としている場合は、オブジェクトの値を上書きしたくありません。これは、スレッド化されたプログラムで可変データ構造の所有権の概念が非常に重要である Java で特に当てはまります。
生のポインターはどうですか?
生のポインターを使用しても、所有権がないわけではありません。変数宣言で記述されていないだけです。コメント、設計ドキュメントなどに記述できます。
そのため、多くの C++ プログラマーは、適切なスマート ポインターの代わりに生のポインターを使用することは劣っていると考えています。これは、表現力が低いためです (意図的に「良い」と「悪い」という用語を避けています)。Linux カーネルは、関係を表現するためにいくつかの C++ オブジェクトを使用すると、より読みやすくなると思います。
スマート ポインターの有無にかかわらず、特定のデザインを実装できます。スマート ポインターを適切に使用する実装は、多くの C++ プログラマーによって優れていると見なされます。
あなたの本当の質問
C++ プロジェクトで、"this" の使用に関する優れた設計哲学は何ですか?
それはひどく漠然としています。
後で使用するために生のポインターを保存するのは危険です。
後で使用するためにポインターが必要なのはなぜですか?
オブジェクトの削除の制御を放棄し、責任のあるコンポーネントが適切なタイミングでそれを実行することを信頼しています。
実際、一部のコンポーネントは変数の存続期間に関与しています。責任を負うことはできません。譲渡する必要があります。
これを別の変数に保存したり、後で保存したり、コールバックでバインドしたりする可能性のある別の関数に渡すと、誰かが私のクラスを使用することを決定したときに導入されるバグが発生します。
明らかに、関数がポインターを非表示にし、呼び出し元の制御なしで後でそれを使用することが呼び出し元に通知されないため、バグが作成されます。
解決策は明らかに次のいずれかです。
- オブジェクトの存続期間を処理する責任を関数に移す
- ポインターが呼び出し元の制御下でのみ保存および使用されるようにする
最初のケースでのみ、クラスの実装でスマート ポインターになる可能性があります。
あなたの問題の原因
あなたの問題は、スマートポインターを使用して問題を複雑にしようとしていることにあると思います。スマート ポインターは、物事を難しくするのではなく、簡単にするためのツールです。スマート ポインターが仕様を複雑にする場合は、より単純な観点から仕様を再考してください。
問題が発生する前に、ソリューションとしてスマート ポインターを導入しようとしないでください。
明確に定義された特定の問題を解決するためにのみ、スマート ポインターを導入します。明確に定義された特定の問題について説明していないため、特定の解決策(スマート ポインターを含むかどうか)について議論することはできません。