try、throw、catch ステートメント (C++)
C++ で例外処理を実装するには、try
、throw
、catch
の式を使用します。
まず、try
ブロックを使用して、例外をスローする可能性がある 1 つ以上のステートメントを囲みます。
throw
は、try
ブロックで例外条件 (多くの場合はエラー) が発生したことを通知するために使用します。 任意の型のオブジェクトを throw
式のオペランドとして使用できます。 通常、このオブジェクトを使用してエラーに関する情報を通知します。 ほとんどの場合、標準ライブラリで定義されているクラスまたは派生クラスの 1 つを使用 std::exception
することをお勧めします。 これらのいずれかが適切でない場合は、独自の例外クラス std::exception
を派生することをお勧めします。
スローされる可能性のある例外を処理するために、1 つ以上の catch
ブロックを try
ブロックの直後に実装します。 各 catch
ブロックには、処理できる例外の型を指定します。
次の例では、try
ブロックとそのハンドラーを示しています。 GetNetworkResource()
では、ネットワーク接続を介してデータを取得するとします。また、2 つの型の例外として std::exception
から派生させたユーザー定義のクラスを使用するとします。 例外は catch
ステートメントの const
参照でキャッチしています。 例外は値でスローし、const 参照でキャッチすることをお勧めします。
例
MyData md;
try {
// Code that could throw an exception
md = GetNetworkResource();
}
catch (const networkIOException& e) {
// Code that executes when an exception of type
// networkIOException is thrown in the try block
// ...
// Log error message in the exception object
cerr << e.what();
}
catch (const myDataFormatException& e) {
// Code that handles another exception type
// ...
cerr << e.what();
}
// The following syntax shows a throw expression
MyData GetNetworkResource()
{
// ...
if (IOSuccess == false)
throw networkIOException("Unable to connect");
// ...
if (readError)
throw myDataFormatException("Format error");
// ...
}
解説
try
句の後のコードは、コードの保護されたセクションです。 throw
式が例外をスローします (発生させます)。 catch
句の後ろのコード ブロックが例外ハンドラーです。 このハンドラーは、throw
式と catch
式とで例外の型が一致する場合に、スローされた例外をキャッチします。 catch
ブロックの型の一致を決定する規則の一覧については、「catch ブロックの評価方法」を参照してください。 catch
ステートメントで型ではなく省略記号 (...) を指定した場合、catch
ブロックはいずれの型の例外も処理します。 このオプションを使用して /EHa
コンパイルすると、C 構造化例外や、メモリ保護、0 除算、浮動小数点違反などのシステム生成またはアプリケーションによって生成された非同期例外を含めることができます。 catch
ブロックは一致する型を検索するプログラムの順序で処理されるため、省略記号を指定したハンドラーは関連付ける try
ブロックの最後のハンドラーにする必要があります。 catch(...)
catch ブロックがキャッチされた特定の例外を処理する方法を認識していない限り、プログラムを続行しないように注意してください。 catch(...)
ブロックは通常、プログラムの実行を停止する前に、エラーを記録して特別なクリーンアップを実行するために使用します。
throw
オペランドを持たない式は、現在処理されている例外を再スローします。 例外を再スローする場合は、元の例外のポリモーフィックな型情報が保持されるため、この形式をお勧めします。 このような式は catch
ハンドラー内か、catch
ハンドラーから呼び出された関数内でのみ使用する必要があります。 再スロー例外オブジェクトは、コピーではなく、元の例外オブジェクトです。
try {
throw CSomeOtherException();
}
catch(...) {
// Catch all exceptions - dangerous!!!
// Respond (perhaps only partially) to the exception, then
// re-throw to pass the exception to some other handler
// ...
throw;
}
関連項目
例外とエラー処理に関する最新の C++ のベスト プラクティス
キーワード
未処理の C++ 例外
__uncaught_exception