[解決済み] スマートポインタ:オブジェクトは誰のものか?[クローズド]
質問
C++はメモリ所有権がすべて - aka 所有権セマンティクス .
動的に割り当てられたメモリのチャンクの所有者は、そのメモリを解放する責任があります。ですから、問題は本当に誰がメモリを所有しているかになります。
C++では、所有権は 生 ポインタの内側にラップされているため、優れた(IMO)C++プログラムでは、非常に稀です ( レア ではなく 決して のように、生のポインタが渡されるのを見ることはできません(生のポインタは所有者が推測できないため、誰がそのメモリを所有しているかがわからず、ドキュメントを注意深く読まないと、誰が所有権に責任があるのかがわかりません)。
逆に、生のポインタがクラス内に格納されているのを見るのは稀で、それぞれの生のポインタはそれ自身のスマートポインタラッパー内に格納されています。 ( N.B: オブジェクトを所有していない場合、いつスコープ外に出て破壊されるか分からないので、格納すべきではありません)。
そこで質問です。
- 人々はどのような所有権の意味合いに遭遇したことがありますか?
- それらのセマンティクスを実装するために、どのような標準クラスが使用されていますか?
- どのような場面で有用だと感じますか?
回答ごとに1種類のセマンティック・オーナーシップを維持し、個別に投票できるようにしましょう。
要約です。
概念的には、スマート ポインターは単純であり、素朴な実装は簡単です。私は多くの実装を試したことがありますが、必ずと言っていいほど、カジュアルな使い方や例ではわからないような方法で壊れています。したがって、私は、自分でスマートポインタを作るよりも、ライブラリから十分にテストされたスマートポインタを常に使用することをお勧めします。
std::auto_ptr
やBoostスマートポインタの1つは、私のすべてのニーズをカバーしているように見えます。
std::auto_ptr<T>
:
一人がオブジェクトを所有する。所有権の譲渡は可能です。
使用方法 これにより、所有権の明示的な譲渡を示すインターフェースを定義することができます。
boost::scoped_ptr<T>
所有者は一人です。所有権の譲渡は認められません。
使用方法。所有権を明示的に示すために使用します。オブジェクトはデストラクタで破棄されるか、明示的にリセットされる。
boost::shared_ptr<T>
(
std::tr1::shared_ptr<T>
)
複数所有権です。これは単純な参照カウントのポインタです。参照カウントが0になると、そのオブジェクトは破棄されます。
使用方法 オブジェクトが、コンパイル時に決定できない寿命を持つ複数の所有者を持つことができる場合。
boost::weak_ptr<T>
:
で使用される
shared_ptr<T>
で、ポインタの循環が起こりうる状況で使用されます。
使用方法 サイクルのみが共有Refcountを維持しているときに、サイクルがオブジェクトを保持するのを止めるために使用します。
どのように解決するのですか?
私の場合、この3種類でほとんど用が足ります。
shared_ptr
- 参照カウント式で、カウンタがゼロになると解放されます。
weak_ptr
- 上記と同じですが、「スレーブ」として
shared_ptr
に対する「スレーブ」であるため、割り当てを解除することができません。
auto_ptr
- 作成と割り当て解除が同じ関数内で行われる場合、またはオブジェクトが常に一人の所有者のみとみなされる必要がある場合です。あるポインターを別のポインターに割り当てるとき、2 番目のポインターは最初のポインターからオブジェクトを「盗む」のです。
私はこれらのために独自の実装を持っていますが、これらはまた
Boost
.
私は今でもオブジェクトを参照渡し (
const
この場合、呼び出されたメソッドはオブジェクトが呼び出されている間だけ生きていると仮定しなければなりません。
と呼んでいる、私が使っているもう一つの種類のポインタがあります。
ハブ変数
. それは、その中にネストされたオブジェクトからアクセスできなければならないオブジェクトがある場合です(通常は仮想基底クラスとして)。これを解決するには
weak_ptr
を渡せばいいのですが、これには
shared_ptr
は持っていません。これらのオブジェクトが彼よりも長生きしないことを知っているので、hub_ptrを渡します(これは通常のポインタに対する単なるテンプレートラッパーです)。
関連
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】C++プログラムでのコンソールの一時停止
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] リファレンスとポインタの使い分け
-
[解決済み】C/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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】C++の変数はイニシャライザーを持っているが、不完全な型?
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】デバッグアサーションに失敗しました
-
[解決済み] 警告:暗黙の定数変換でのオーバーフロー
-
[解決済み] 変数サイズのオブジェクトが初期化されないことがある c++
-
[解決済み] スマートポインターとは何ですか?