C++ 例外処理
例外とは、プログラムの実行中に発生する問題です。C++ の例外とは、プログラムの実行時に発生する特別な状況、例えばゼロ除算の試みなどを指します。
例外は、プログラムの制御を移す方法を提供します。C++ の例外処理には3つのキーワードが関わります:try、catch、throw。
- throw:問題が発生すると、プログラムは例外をスローします。これは次のものを使用して行われます。throwキーワードによって行われます。
- catch:問題を処理したい場所で、例外ハンドラによって例外をキャッチします。catchキーワードは例外をキャッチするために使用されます。
- try: tryブロック内のコードは、アクティブになる特定の例外を識別します。その後に通常1つ以上の catch ブロックが続きます。
ブロックが例外をスローする場合、例外をキャッチする方法ではtryとcatchcatch キーワードを使用します。try ブロックには例外をスローする可能性のあるコードを配置し、try ブロック内のコードは保護コードと呼ばれます。try/catch 文の構文は次のとおりです:
もしtryブロックが異なる状況で異なる例外をスローする場合、このとき複数のcatchcatch 文を列挙して、異なるタイプの例外をキャッチすることができます。
例外をスローする
あなたは次を使用できます:throwthrow 文。コードブロック内の任意の場所で例外をスローできます。throw 文のオペランドは任意の式であり、式の結果の型がスローされる例外の型を決定します。
以下は、ゼロ除算を試みたときに例外をスローする例です:
例外をキャッチする
catchcatch ブロックはtrytry ブロックの後に続き、例外をキャッチするために使用されます。キャッチしたい例外の型を指定できます。これは、catch キーワードの後の括弧内の例外宣言によって決定されます。
上記のコードは、型が次のものである例外をキャッチします。ExceptionNameの例外をキャッチします。catch ブロックに try ブロックがスローするあらゆる型の例外を処理させたい場合は、例外宣言の括弧内に省略記号 ... を使用する必要があります。次のようになります:
以下は、ゼロ除算の例外をスローし、catch ブロックでその例外をキャッチする例です。
例
私たちは型が次のものである例外をスローしたため、const char*の例外をスローしたため、その例外をキャッチするときは、catch ブロックで const char* を使用する必要があります。上記のコードがコンパイルおよび実行されると、次の結果が生成されます:
Division by zero condition!
C++ 標準の例外
C++ は一連の標準例外を提供しており、それらは次に定義されています。<exception>の中に定義されています。プログラム内でこれらの標準例外を使用できます。それらは親子クラスの階層構造で編成されており、次のようになります:
次の表は、上記の階層構造に登場する各例外の説明です:
| 例外 | 説明 |
|---|---|
| std::exception | この例外は、すべての標準 C++ 例外の親クラスです。 |
| std::bad_alloc | この例外はnewによってスローされます。 |
| std::bad_cast | この例外はdynamic_castによってスローされます。 |
| std::bad_typeid | この例外はtypeidによってスローされます。 |
| std::bad_exception | これは、C++ プログラムで予期しない例外を処理するときに非常に役立ちます。 |
| std::logic_error | 理論的にはコードを読むことで検出できる例外です。 |
| std::domain_error | 無効な数学ドメインを使用したときに、この例外がスローされます。 |
| std::invalid_argument | 無効な引数を使用したときに、この例外がスローされます。 |
| std::length_error | 長すぎる std::string を作成したときに、この例外がスローされます。 |
| std::out_of_range | この例外は、std::vector や std::bitset<>::operator[]() などのメソッドによってスローされます。 |
| std::runtime_error | 理論的にはコードを読むことで検出できない例外です。 |
| std::overflow_error | 数学的なオーバーフローが発生したときに、この例外がスローされます。 |
| std::range_error | 範囲外の値を格納しようとしたときに、この例外がスローされます。 |
| std::underflow_error | 数学的なアンダーフローが発生したときに、この例外がスローされます。 |
新しい例外の定義
あなたは、exceptionクラスを継承およびオーバーロードすることで、新しい例外を定義できます。次の例は、std::exception クラスを使用して独自の例外を実装する方法を示しています:
例
これにより、次の結果が生成されます:
MyException caught C++ Exception
ここで、what()は例外クラスが提供するパブリックメソッドであり、すべてのサブ例外クラスによってオーバーロードされています。これは例外が発生した原因を返します。
その他の拡張