try、throw、および catch ステートメント (C++)try, throw, and catch Statements (C++)

でC++例外処理を実装するには、 trythrow、およびcatch式を使用します。To implement exception handling in C++, you use try, throw, and catch expressions.

最初に、try ブロックを使用し、例外をスローする可能性のある1つ以上のステートメントを囲みます。First, use a try block to enclose one or more statements that might throw an exception.

Throw式は、 tryブロックで例外的な条件 (多くの場合、エラー) が発生したことを通知します。A throw expression signals that an exceptional condition—often, an error—has occurred in a try block. 任意の型のオブジェクトをthrow式のオペランドとして使用できます。You can use an object of any type as the operand of a throw expression. 通常、このオブジェクトを使用してエラーに関する情報を通知します。Typically, this object is used to communicate information about the error. ほとんどの場合、 std:: exceptionクラス、または標準ライブラリで定義されている派生クラスの1つを使用することをお勧めします。In most cases, we recommend that you use the std::exception class or one of the derived classes that are defined in the standard library. これらのいずれのクラスも適さない場合は、std::exception から派生させた独自の例外クラスを使用することをお勧めします。If one of those is not appropriate, we recommend that you derive your own exception class from std::exception.

スローされる可能性のある例外を処理するには、 tryブロックの直後に1つ以上のcatchブロックを実装します。To handle exceptions that may be thrown, implement one or more catch blocks immediately following a try block. catchブロックは、処理できる例外の種類を指定します。Each catch block specifies the type of exception it can handle.

この例では、 tryブロックとそのハンドラーを示します。This example shows a try block and its handlers. GetNetworkResource() では、ネットワーク接続を介してデータを取得するとします。また、2 つの型の例外として std::exception から派生させたユーザー定義のクラスを使用するとします。Assume that GetNetworkResource() acquires data over a network connection and that the two exception types are user-defined classes that derive from std::exception. Catchステートメントでconst参照によって例外がキャッチされていることに注意してください。Notice that the exceptions are caught by const reference in the catch statement. 例外は値でスローし、const 参照でキャッチすることをお勧めします。We recommend that you throw exceptions by value and catch them by const reference.

Example

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");
   // ...
}

コメントRemarks

Try句の後のコードは、コードの保護されたセクションです。The code after the try clause is the guarded section of code. Throw式は、例外をスローします。The throw expression throws—that is, raises—an exception. Catch句の後のコードブロックは、例外ハンドラーです。The code block after the catch clause is the exception handler. これは、 throwおよびcatch式の型に互換性がある場合にスローされる例外をキャッチするハンドラーです。This is the handler that catches the exception that's thrown if the types in the throw and catch expressions are compatible. Catchブロックでの型の一致を制御する規則の一覧については、「 Catch ブロックの評価方法」を参照してください。For a list of rules that govern type-matching in catch blocks, see How Catch Blocks are Evaluated. Catchステートメントで型の代わりに省略記号 (...) が指定されている場合、 catchブロックはすべての種類の例外を処理します。If the catch statement specifies an ellipsis (...) instead of a type, the catch block handles every type of exception. /Ehaオプションを使用してコンパイルすると、C 構造化例外、システム生成、またはアプリケーションによって生成される非同期例外 (メモリ保護、0除算、浮動小数点違反など) が含まれることがあります。When you compile with the /EHa option, these can include C structured exceptions and system-generated or application-generated asynchronous exceptions such as memory protection, divide-by-zero, and floating-point violations. Catchブロックはプログラムの順序で処理され、一致する型が検出されるため、省略記号ハンドラーは、関連付けられている tryブロックの最後のハンドラーである必要があります。Because catch blocks are processed in program order to find a matching type, an ellipsis handler must be the last handler for the associated try block. catch(...) は慎重に使用してください。プログラムの実行が継続されるには、キャッチした特定の例外を処理する方法を catch ブロックに記述する必要があります。Use catch(...) with caution; do not allow a program to continue unless the catch block knows how to handle the specific exception that is caught. catch(...) ブロックは通常、プログラムの実行を停止する前に、エラーを記録して特別なクリーンアップを実行するために使用します。Typically, a catch(...) block is used to log errors and perform special cleanup before program execution is stopped.

オペランドが指定されていないthrow式は、現在処理中の例外を再スローします。A throw expression that has no operand re-throws the exception currently being handled. この方法は例外を再スローするときにお勧めします。元の例外のポリモーフィックな型情報が保持されるためです。We recommend this form when re-throwing the exception, because this preserves the original exception’s polymorphic type information. このような式は、catch ハンドラーまたcatchハンドラーから呼び出された関数でのみ使用してください。Such an expression should only be used in a catch handler or in a function that's called from a catch handler. 再スローされた例外オブジェクトはコピーではなく元の例外オブジェクトです。The re-thrown exception object is the original exception object, not a copy.

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;
}

参照See also

例外C++とエラー処理に関する最新のベストプラクティスModern C++ best practices for exceptions and error handling
キーワードKeywords
未処理の C++ 例外Unhandled C++ Exceptions
__uncaught_exception__uncaught_exception