重要
std::auto_ptr
これには多くの欠点がありstd::unique_ptr
、コンパイラで提供されている場合は、通常は代わりに使用する必要があることに注意してください。(そうでない場合は、コンパイラを更新してください! :))
さて、あなたの質問に戻ります...
この auto_ptr を使用する意味は何ですか? 通常のクラス初期化変数 (a) として、スコープ外に出るときにクラス デストラクタを呼び出します。
丁度。その理由auto_ptr
は、厳密な所有権のセマンティクスを強制するためです。これにより、ポインター自体が破棄されたときにオブジェクトが適切に破棄されます。
このポインターをクラス ポインター (func) を持つ関数に渡すことができません
get()
生ポインタを検索するために使用する必要があります。get()
関数呼び出しにポインターを渡すときに使用すると、関数がオブジェクトの所有権を取得しないことを意味します (オブジェクトはauto_ptr
まだ所有しており、関数が戻った後も有効であることが期待されます)。
または、 on を使用release()
して未加工のポインターを取得しauto_ptr
、オブジェクトの所有権がもはや責任を負わないことを示すことができます。
auto_ptr は delete[] ではなく delete を呼び出すため、A[] または char[] にポインター auto_ptr を使用することはできません。
うん、それは問題だ。が導入されauto_ptr
てから使用しなくなった理由の 1 つです。unique_ptr
同じことを行いますが、より安全に (= 簡単に) 使用でき、より汎用性があります。
唯一の考えは、delete を書く必要はないということですが、範囲外に出たときに破棄される場合、ポインターの意味は何ですか。
あなたがそれを忘れないように:-)または、auto_ptr
(またはunique_ptr
クラスオブジェクトのメンバーとしてより良い)を使用できます。
しかし、通常のポインターではなく auto_ptr を使用する意味を教えてください。
簡単に言えば、多くのポインターが単一のオブジェクトを指すことができます。あらゆる種類のスマート ポインターが存在し、どのポインターがオブジェクトを所有するか (= オブジェクトを解放する責任があるか) を記帳するために型システムを使用します。
補足
別のオブジェクトのインスタンスを所有する (可能性がある) クラスがある場合は、単純に次のように記述します。
class X {
// ...
X() : ptr(new Type()) {}
X(Type ptr) : ptr(ptr) {}
// ...
void setPtr(Type ptr2) { ptr.reset(ptr); }
// ...
std::unique_ptr<Type> ptr;
};
が設定されている場合ptr
、たとえばunique_ptr
のデストラクタがオブジェクトの削除を処理します (存在する場合)。setPtr
メソッドでは、関数reset()
は古いインスタンス (存在する場合) を削除し、メンバーを提供された新しいインスタンス (または null - OK) に設定します。
次に、別の状況を比較します。
class X {
// ...
X() : ptr(new Type()) {}
X(Type ptr) : ptr(ptr) {}
// ...
void setPtr(Type ptr2) {delete ptr; ptr = ptr2;}
// ...
Type* ptr;
};
同じ振る舞い?いいえ!ptr
現在、安全な C++ コードを作成するには、 が破棄されたときに削除するデストラクタを追加で記述する必要があるためX
です。
今いいよ?いいえ!共通のデストラクタがあるため、独自のコピー コンストラクタと代入演算子をロールアップ (またはブロック) する必要があるためです。そうしないと、X の 2 つのインスタンスが同じ Type オブジェクトを指すことになり、両方のインスタンスがここで彼らはこのインスタンスを所有しており、両方がいつかそれを削除しようとします。ドーン、アクセス違反。
ptr
Unique_ptrは への強い参照とともに X オブジェクトを暗黙的にコピーすることを許可しません。-しかし、所有していないものを削除しようとしない限り、未加工の所有していないポインターがそれを指していても問題ありません!)。
これだけではありません。unique_ptr はコピーできませんが、移動コンストラクターと移動代入演算子が用意されています。したがって、関数などから安全に返すことができます。
これは、スマート ポインターのタイプ セーフが、より安全なコードの記述に変換される方法です。
黄金律: "delete" を記述しないようにしてください (独自のコンテナーまたはスマート ポインターを記述している場合を除く)。:)