エラー:「char」のインスタンスをスローした後に呼び出された終了



Error Terminate Called After Throwing An Instance Ofchar



C ++デストラクタ例外
zhuan http://blog.etrnls.net/2008/06/03/cpp_destructor_exception/#more-72

C ++標準では、デストラクタは例外をスローしないとされており、特定の場合にデストラクタが例外をスローすると、自動的にterminate()を呼び出してプログラムを終了します。



「腰痛なしで立って話す」というこの仮説を見てみましょう。最初に明確にすることは、C ++例外がオブジェクト指向とシームレスに統合されていることです。当然、例外が発生したときにローカル変数が正常に破棄されるようにする必要があります。例外がスローされると、スタックの巻き戻しプロセスがあります。つまり、例外のスローポイントと最も近いcatch例外の間のすべてのスタックページがポップされ、ページ内のすべてのローカルオブジェクトが破棄され、破棄されていることがわかります。例外処理と密接に組み合わされています。

ここで、デストラクタを呼び出すために例外がアクティブ化され(MyExceptionをどこかにスローするなど)、デストラクタが例外(AnotherExceptionなど)をスローした場合、どうすればよいですか?この新しい例外を無視して、MyExceptionをキャッチする場所を探し続けるのですか、それともMyExceptionをスローして、AnotherExceptionを処理する場所を見つけ始めるのですか?



したがって、C ++言語は、この時点で、プロセスを強制終了するためにterminate()が呼び出されることを保証します。したがって、デストラクタで例外をスローした場合、誰かがそれをキャッチすることを期待しないでください。

デストラクタが本当に例外をスローした場合はどうなりますか?実際、これは避けられない場合があり、デストラクタ内でこの例外を制御する必要があります。実行しないようにする必要があります。実行の結果が想像を絶すると、プログラムがクラッシュする可能性があります。

そして、私たちがプログラムを書くとき、標準が言うように、デフォルトの破壊は例外を生み出しません。



最後に、デモンストレーション用のコードを見てください〜

#include #include using namespace std class Foo { public: Foo() { cerr << 'Foo ctor' << endl } ~Foo() { cerr << 'Foo dtor' << endl throw 'Bad exception!' } void doSomething() { throw 'The exception' } } class Bar { public: Bar() { cerr << 'Bar ctor' << endl } ~Bar() { cerr << 'Bar dtor' << endl } } void fun1() { Foo foo foo.doSomething() } void fun2() { Bar bar fun1() } void fun3() { try { fun2() } catch (...) { cerr << 'Caught exception' << endl } } int main() { fun3() return 0 }

操作の結果(g ++(GCC)4.1.2(Gentoo 4.1.2 p1.1)コンパイル済み):

バークター
Foo ctor
Foo dtor
「charconst *」のインスタンスをスローした後に呼び出された終了
中止
さて、バーのデストラクタは呼び出されず、プログラムは直接終了します。もちろん、doSomethingが例外をスローしない場合、このプログラムは正常に終了できるため、元のコードが正常に実行され、コードの新しい部分がクラッシュすることがあります。新しいコードを確認しても何も見つかりません。問題は、実際、元のコードの「適切な」操作は単なる架空のものです...

PS:少し部分的です。コンストラクターが例外をスローした場合、デストラクタは呼び出されません。 C ++は、オブジェクトが実際には「ライブ」ではないと見なすため、「デッド」にする必要はありません。また、Object Pascalは、コンストラクターと見なすと言われています。スローされる例外は、オブジェクトが「ハーフライブ」であるため、次のことを行う必要があります。デストラクタを呼び出して「デッド」にします。