何が起こっているのかというと、このexit()
関数は、すべてのグローバルオブジェクトのデストラクタを呼び出すようにプログラムを取得しています。また、クラスのデストラクタがオブジェクトを呼び出した時点ではexit(1);
、オブジェクトはまだ破壊されているとは見なされていないため、デストラクタが再度呼び出され、無限ループが発生します。
あなたはこれで逃げることができます:
class sample {
bool exiting;
public:
sample() { exiting = false; }
~sample() {
cout << "Destructing.." << endl;
if(exiting) return;
exiting = true;
exit(0);
}
};
しかし、デストラクタを呼び出すexit()
ことは悪い考えです。これらの選択肢の1つを検討してください。
- 終了するための別の通常の(非デストラクタ)メソッドを作成します
- 「プログラム」が終了するまで実行される関数を作成し、
main()
abort()
代わりに使用exit()
してください(これについて言及してくれたgoldilocksに感謝します)。 が呼び出さabort()
れたときと戻ったときに通常実行されるすべてのクリーンアップをバイパスします。ただし、プログラム内の特定のクリーンアップ操作が非常に重要になる可能性があるため、これも必ずしも良い考えではありません。 クリーンアップをバイパスすることが保証されているほどすでにひどいエラーのみを対象としています。exit()
main()
abort()
以前に例外を提案しましたが、内部のデストラクタから例外をスローすることを思い出し、考えを変えました。これが理由です。
また、動作に一貫性がないことにも注意してください。一部のコンパイラ/環境では無限ループが発生しますが、そうでないものもあります。デストラクタのどの時点でオブジェクトが破壊されたと見なされるかが決まります。標準はこれをカバーしていないか、この場合の動作は未定義であると言っていると思います。