このコードは正しいですか?
auto v = make_unique<int>(12);
v.release(); // is this possible?
生のポインタのdelete
と同等ですか?
いいえ、コードによりメモリリークが発生します。 release
は、管理対象オブジェクトの所有権を解放するために使用されますwithout削除:
auto v = make_unique<int>(12); // manages the object
int * raw = v.release(); // pointer to no-longer-managed object
delete raw; // needs manual deletion
セーフティネットなしで生のメモリをジャグリングする正当な理由がない限り、これを行わないでください。
オブジェクトを削除するには、reset
を使用します。
auto v = make_unique<int>(12); // manages the object
v.reset(); // delete the object, leaving v empty
このコードは正しいですか?
いいえ。std::unique_ptr<>::reset()
を使用して、内部rawポインターを削除します。
_auto v = std::make_unique<int>(12);
v.reset(); // deletes the raw pointer
_
その後、std::unique_ptr<>::get()
はnullptr
を返します(std::unique_ptr<>::reset()
にnullptr
以外のパラメーターを指定した場合を除く)。
このコードは正しいですか?
そうではなく、リークします。
release()
は、呼び出し元のコードが、_unique_ptr
_が呼び出されるまで保持していたメモリの所有権を取り戻すだけです。 release()
によって返されるポインタを割り当てないと、リークが発生します。
_unique_ptr
_の明示的な削除はreset()
になります。ただし、_unique_ptr
_が存在するため、保持するメモリを直接管理する必要はありません。つまり、_unique_ptr
_はスコープから外れると、元の生のポインターを安全に削除することを知っておく必要があります。
したがって、自動メモリ管理オブジェクトに対して手動メモリ管理を実行する非常に良い理由が必要です。
release
は、何にも割り当てないため、生のポインタをリークします。
それは次のようなものに使用されることを意図しています
int* x = v.release();
つまり、v
はそのポインターの有効期間を管理しなくなり、生のポインターの所有権をx
に委任します。何も割り当てずにrelease
だけを使用すると、生のポインターがリークします。
任意の型には少し注意が必要です。
unique_ptr<Foo> v = get_me_some_foo(); // manages the object
Foo * raw = v.release(); // pointer to no-longer-managed object
delete raw;
ほぼ正しいです。
unique_ptr<Foo> v = get_me_some_foo(); // manages the object
Foo * ptr = v.release(); // pointer to no-longer-managed object
v.get_deleter() ( ptr );
これはすべての状況で正しいでしょう。 Foo型で定義されたカスタム削除機能がある場合がありますが、unique_ptrオブジェクトによって返される削除機能を使用することは、すべての場合に適しています。