関数内でオブジェクトを新規作成する場合、関数の終了前にポインターで削除を呼び出す必要がありますか、または関数の終了後に自動的に呼び出されるデストラクタで削除の仕事をしますか?
関数から戻ると、自動保存期間を持つすべてのローカル オブジェクトが破棄されます。それらがクラス型である場合、それらが占有していたストレージが取り戻される前に、それらのデストラクタが呼び出されます。それらが非クラス型 ( などint
) の場合、呼び出すデストラクタはありません。
ここで、自動保存期間を持つ唯一のローカル オブジェクトはポインターa
(! が指すオブジェクトではないことに注意してくださいa
) であり、ポインターはクラス型ではありません。これは、それa
が破棄されることを意味し、それだけです。特に、オブジェクトがa
指すオブジェクトは破棄されません。
したがって、delete
関数を終了する前に呼び出す必要があります (終了するかreturn
、例外をスローして終了するかに関係なく)。一般に、 への各呼び出しを への呼び出しと常に一致させ、 への各呼び出しを へnew
の呼び出しと一致させる必要があります。delete
new[]
delete[]
. delete
_ new
_デストラクタが構築中に取得したリソースをクリーンアップするためのものであるローカル オブジェクトです。
例えば:
void foo()
{
auto p = std::make_unique<A>(); // OK, make_unique() will only be available
// in C++14. Meanwhile, in C++11 you can do:
//
// std::unique_ptr<A> p(new A());
// Work with p...
// No memory leak here!
}
C++11 の使用が許可されていない場合、たとえば上司が、互換性の理由から SW は古いバージョンのコンパイラでコンパイルする必要があると言っている場合は、いつでも上司boost::shared_ptr
を強制終了して、 やなどの Boost のスマート ポインター クラスを使用できますboost::scoped_ptr
。
とにかく、必要でない限り、動的割り当てを実行しないでください。必要がない場合 (たとえば、そのオブジェクトの所有権を他の関数と共有する必要がない場合)、A
オブジェクトに自動ストレージ期間を与えるだけで、スコープ外に出たときにデストラクタが呼び出されるようにすることができます。 :
void foo()
{
A a;
// Work with a...
// a will be destroyed when returning from foo()
}