try、throw、catch ステートメント (C++)

C++ で例外処理を実装するには、trythrowcatch の式を使用します。

まず、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