コンパイラーが try ブロックで例外を検出すると、その出現の順に各ハンドラーを試行します
基底クラスから派生したクラスのオブジェクトの catch ブロックの前に、 その基底クラスのオブジェクトの catch ブロックがある場合、コンパイラーは、警告を発行し、 派生クラス・ハンドラーで到達不能コードであるにもかかわらず、プログラムのコンパイルを継続します。
catch(...) の書式の catch ブロックは、try ブロックの後に続く最後の catch ブロックでなければならず、そうでなければエラーが起こります。 このように配置することによって、catch(...) ブロックによって、さらに特定の catch ブロックが、本来 キャッチすることになっている例外をキャッチすることを防ぐことができなくなります。
ランタイムが、現行スコープ内に一致するハンドラーを検出できない場合、ランタイムは、動的な囲み try ブロック内で 一致するハンドラーの検出を継続します。 次の例は、このことを示しています。
#include <iostream> using namespace std; class E { public: const char* error; E(const char* arg) : error(arg) { }; }; class F : public E { public: F(const char* arg) : E(arg) { }; }; void f() { try { cout << "In try block of f()" << endl; throw E("Class E exception"); } catch (F& e) { cout << "In handler of f()"; cout << e.error << endl; } };
int main() { try { cout << "In main" << endl; f(); } catch (E& e) { cout << "In handler of main: "; cout << e.error << endl; }; cout << "Resume execution in main" << endl; }
次に、上記の例の出力を示します。
In main In try block of f() In handler of main: Class E exception Resume execution in main
関数 f() では、ランタイムは、スローされた型 E の例外を 処理するハンドラーを検出できません。 ランタイムは、動的な囲み try ブロック内、つまり main() 関数の try ブロック内で、一致するハンドラーを検出します。
ランタイムがプログラム内で、一致するハンドラーを検出できない場合は、terminate() 関数を呼び出します。
関連参照