catch ブロックが、キャッチした特定の例外を処理できない場合、
その例外を再スローする (rethrow) ことができます。
rethrow 式 (assignment_expression がない throw) は、最初にスローされたオブジェクトを再びスローします。
例外が、rethrow 式が発生するスコープですでにキャッチされているので、その例外は、次の動的な囲み try ブロックへ再びスローされます。 したがって、rethrow 式の発生したスコープの catch ブロックは、その例外を処理できなくなります。 動的な囲み try ブロックの catch ブロックは、いずれも、例外をキャッチする機会があります。
次の例は、例外の再スローを示しています。
#include <iostream> using namespace std; struct E { const char* message; E() : message("Class E") { } }; struct E1 : E { const char* message; E1() : message("Class E1") { } }; struct E2 : E { const char* message; E2() : message("Class E2") { } }; void f() { try { cout << "In try block of f()" << endl; cout << "Throwing exception of type E1" << endl; E1 myException; throw myException; } catch (E2& e) { cout << "In handler of f(), catch (E2& e)" << endl; cout << "Exception: " << e.message << endl; throw; } catch (E1& e) { cout << "In handler of f(), catch (E1& e)" << endl; cout << "Exception: " << e.message << endl; throw; } catch (E& e) { cout << "In handler of f(), catch (E& e)" << endl; cout << "Exception: " << e.message << endl; throw; } } int main() { try { cout << "In try block of main()" << endl; f(); } catch (E2& e) { cout << "In handler of main(), catch (E2& e)" << endl; cout << "Exception: " << e.message << endl; } catch (...) { cout << "In handler of main(), catch (...)" << endl; } }
次に、上記の例の出力を示します。
In try block of main() In try block of f() Throwing exception of type E1 In handler of f(), catch (E1& e) Exception: Class E1 In handler of main(), catch (...)main() 関数の try ブロックは、関数 f() を呼び出します。 関数 f() の try ブロックは、myException という名前の、型 E1 のオブジェクトをスローします。 ハンドラー catch (E1 &e) が、myException キャッチします。 それからハンドラーは、ステートメント throw を使用して、myException を、次の動的な 囲み try ブロック、つまり main() 関数の try ブロックに再びスローします。 ハンドラー catch(...) が myException をキャッチします。
関連参照