1

delete 演算子と、それがクラスのデストラクタを自動的に呼び出す方法について知っています。しかし、最近、誰かがクラスのデストラクタを直接呼び出すのを見たことがありますが、これは非常に奇妙に思えました。だから私は本当に予期しない結果をもたらす短いプログラムを書きました:

#include <stdio.h>

class A
{
public:
  A()  {a = new int; *a=42; b=33;}
  ~A() {delete a;}

  int* a;
  int  b;
};

int main(int argc, const char ** argv)
{
  A* myA = new A();
  printf("a:%d  b:%d\n", *(myA->a), myA->b);
  myA->~A();
  printf("b:%d\n", myA->b);
  printf("a:%d\n", *(myA->a));
}

ご覧のとおり、デストラクタ ~A() を呼び出しているので、変数 'a' にもう一度アクセスしようとすると、プログラムがクラッシュするはずです (2 行前に削除されたため)。代わりに..プログラムは文句なしにこれを出力します:

a:42  b:33
b:33
a:42

... どうして?~A() を直接呼び出すとどうなりますか? そうすることが役立つ状況はありますか?

4

4 に答える 4

10

デストラクタを手動で呼び出すことは、関数を呼び出すことに似ていますdelete。メモリが解放されたときに を呼び出すのとは対照的に、コードは実行されますが、メモリは解放されません。

削除後にアクセスaすると、未定義の動作が発生し、動作しているように見える場合があります。

于 2013-01-08T12:40:32.457 に答える
5

変数'a'にもう一度アクセスしようとすると、プログラムがクラッシュするはずです。

削除された変数にアクセスすることは未定義の動作です。これは、プログラムのクラッシュを含め、何でも起こり得ることを意味します。

〜A()を直接呼び出すとどうなりますか?

あなたの例では、そのオブジェクトを削除しないので、何もしませんが、削除するべきではありません

そうすることが役立つ状況はありますか?

はい、新しい配置のためにデストラクタを明示的に呼び出す必要があります。これは、デストラクタを呼び出す必要がある唯一のケースです。

于 2013-01-08T12:48:26.453 に答える
3

〜A()を直接呼び出すと、デストラクタのコードが実行されます。これにより、C ++の場合のように、通常、デストラクタが再度呼び出されるのを防ぐことはできません。例えば:

void func()
{
   A a;
   a.~A();  // calls destructor
   // Destructor runs again here as it always would.
}

あなたの例では、intのメモリが解放されます。これは、ランタイムがプログラムがメモリを使用しなくなったことを通知することを意味します...しかし、必ずしもメモリが即座にワイプされたり、他の目的で使用されたりすることを意味するわけではありません。したがって、後でintのメモリにアクセスしても、同じ値が含まれています。ただし、他のスレッドがこのメモリを再利用し、他のスレッドがメモリを上書きした可能性がありますが、それはプログラムで発生することはありません。

〜A()を直接呼び出すと便利な状況は、最適化したい状況に対して独自のメモリ割り当てを処理したい場合です。たとえば、独自の文字列クラスがあり、一度に大量のメモリプールを予約する場合があります。コンストラクタとデストラクタを手動で呼び出して、このプール内のメモリ領域を適切に初期化された文字列に設定できます。新しい割り当てを行うことなく、プールを再利用するだけでこれを行うことができます。しかし...これはエキスパートレベルのプログラミングであり、価値のあるパフォーマンスを向上させるには、自分が何をしているのかを知り、それを実行する必要があります。

于 2013-01-08T12:46:16.100 に答える
2

ご覧のとおり、デストラクタ ~A() を呼び出しているので、変数 'a' にもう一度アクセスしようとすると、プログラムがクラッシュするはずです (2 行前に削除されたため)。代わりに..プログラムは文句なしにこれを出力します:

驚かない。お気づきのように、コードにはバグがあります。つまり、期待どおりに動作するのではなく、予測や理解が難しいものになります。予測どおりに動作するコードが必要な場合は、ルールに従う必要があります。それが彼らの目的です。

「バスケットボールではボールを持って走ることはできないと誰かが私に言った.私はバスケットボールを手に入れて試してみた.うまくいった.彼は明らかにバスケットボールを理解していなかった. -- ロジャー・ミラー

于 2013-01-08T12:41:15.563 に答える