C ++ 03理論
の場合:例外仕様にない例外をスローすると、unexpected()
が呼び出されます。これを介して予期しないハンドラーを設定していない場合は、set_unexpected()
これterminate()
が呼び出されます。これは、観察した場合です。終了を呼び出さないが例外をスローする予期しないハンドラーを設定し、その例外が例外仕様にリストされていない場合、それはbad_exceptionに変換されます。したがって、期待される結果を得るには、set_unexpected()
最初に適切なハンドラーを使用して呼び出します。
C ++ 03の実践では:
一部のコンパイラは(以外のthrow()
)例外仕様をまったくサポートしていませんが、他のコンパイラはそれらが正しいかどうかを評価/チェックしていません。Herb Sutterが指摘しているように、例外仕様は、正しく処理するのが容易ではない不器用な「シャドウタイプシステム」を作成します(可能であれば)。したがって..
... C ++ 11の場合:
例外仕様は非推奨になりました。むしろそれらを使用するべきではありません。ただし、nothrow
機能が少し異なる演算子がありますthrow()
PS:では、なぜC++03にstd::bad_exceptionがあるのですか?
コードには3つの異なる領域があります。
- 例外仕様を作成している関数。
- その関数から呼び出している「外部」コードで、仕様に一致しない例外をスローする場合とスローしない場合があります。
- (おそらく未知の)予期しないハンドラー。これは何でもかまいません。プログラムを終了/終了/中止するか、何かをスローする必要があります。
したがって、「外部」コードが例外仕様に違反する例外をスローした場合、次の3つの結果が考えられます。
- ハンドラーはプログラムを終了します。関数に独自のハンドラーを設定しない限り、それについてできることはあまりありません。
- ハンドラーは、例外仕様に一致する例外をスローします。そして、すべてが順調です。
- ハンドラーは何か他のものをスローします。ランタイムに今何をさせたいですか?そこでbad_exceptionが登場します。仕様に含まれている場合、「何か他のもの」がbad_exceptionに変換され、プログラムが続行されます。そうでない場合は、terminateが呼び出されます。
関数内に独自のハンドラーを設定すると、関数を使用したいだけの人が以前に設定したハンドラーが無効になります。彼はあなたが彼のハンドラーを無効にすることを期待しません。さらに、ハンドラーはグローバルなwhat-happens-ifポリシーとして意図されているため、単一の関数の実装では気にする必要はありません。