1

関数内でオブジェクトを新規作成する場合、関数の終了前にポインターで削除を呼び出す必要がありますか、または関数の終了後に自動的に呼び出されるデストラクタで削除の仕事をしますか?

例えば、

   void f()
   {
     A * a = new A(); // assume A has destructor defined, which frees any dynamically assigned resources
   }


 OR

  void f()
  {
    A * a = new A();
    delete a;
  }

デストラクタの削除と自動呼び出しは同等ですか?

4

5 に答える 5

12

関数内でオブジェクトを新規作成する場合、関数の終了前にポインターで削除を呼び出す必要がありますか、または関数の終了後に自動的に呼び出されるデストラクタで削除の仕事をしますか?

関数から戻ると、自動保存期間を持つすべてのローカル オブジェクトが破棄されます。それらがクラス型である場合、それらが占有していたストレージが取り戻される前に、それらのデストラクタが呼び出されます。それらが非クラス型 ( などint) の場合、呼び出すデストラクタはありません。

ここで、自動保存期間を持つ唯一のローカル オブジェクトはポインターa(! が指すオブジェクトではないことに注意してくださいa) であり、ポインターはクラス型ではありません。これは、それaが破棄されることを意味し、それだけです。特に、オブジェクトがa 指すオブジェクトは破棄されません。

したがって、delete関数を終了する前に呼び出す必要があります (終了するかreturn、例外をスローして終了するかに関係なく)。一般に、 への各呼び出しを への呼び出しと常に一致させ、 への各呼び出しを へnewの呼び出しと一致させる必要があります。deletenew[]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()
}
于 2013-06-20T13:52:52.833 に答える
3

スコープ外に出ると、自動オブジェクトのみが破棄されます。

void f() {
    A a;
} // destroyed here

でオブジェクトを動的に割り当てる場合、newで割り当てを解除するのはあなたの責任deleteです。そうしないと、永久に割り当てられたままになり、メモリリークが発生します。これを正しく管理するのは非常に難しい場合があります。特に、例外によってポインターのスコープを離れる可能性がある場合はなおさらです。

そのため、new本当に必要でない限り使用しないでください。常に共有ポインタまたは他のRAIIオブジェクトを使用して、動的オブジェクトを管理します。

于 2013-06-20T13:51:43.767 に答える