例外の rethrow

C++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 をキャッチします。

関連参照

IBM Copyright 2003