Cplusplus-cpp-exceptions-handling
C ++例外処理
例外は、プログラムの実行中に発生する問題です。 C ++例外は、ゼロ除算の試行など、プログラムの実行中に発生する例外的な状況への応答です。
例外は、プログラムのある部分から別の部分に制御を移す方法を提供します。 C ++例外処理は、* try、catch、、 *throw の3つのキーワードに基づいて構築されています。
- throw -問題が発生すると、プログラムは例外をスローします。 これは、 throw キーワードを使用して行われます。
- catch -プログラムは、問題を処理するプログラム内の場所で例外ハンドラーを使用して例外をキャッチします。 catch キーワードは、例外のキャッチを示します。
- try - try ブロックは、特定の例外がアクティブになるコードのブロックを識別します。 その後に、1つ以上のcatchブロックが続きます。
ブロックが例外を発生させると仮定すると、メソッドは try キーワードと catch キーワードの組み合わせを使用して例外をキャッチします。 try/catchブロックは、例外を生成する可能性のあるコードの周りに配置されます。 try/catchブロック内のコードは保護されたコードと呼ばれ、try/catchを使用するための構文は次のとおりです-
try {
//protected code
} catch( ExceptionName e1 ) {
//catch block
} catch( ExceptionName e2 ) {
//catch block
} catch( ExceptionName eN ) {
//catch block
}
*try* ブロックが異なる状況で複数の例外を発生させた場合に、複数の *catch* ステートメントをリストして、異なるタイプの例外をキャッチできます。
例外を投げる
*throw* ステートメントを使用して、コードブロック内のどこにでも例外をスローできます。 throwステートメントのオペランドは例外のタイプを決定し、任意の式にすることができ、式の結果のタイプはスローされる例外のタイプを決定します。
以下は、ゼロ条件による除算が発生したときに例外をスローする例です-
double division(int a, int b) {
if( b == 0 ) {
throw "Division by zero condition!";
}
return (a/b);
}
例外をキャッチする
*try* ブロックに続く *catch* ブロックは、例外をキャッチします。 キャッチする例外のタイプを指定できます。これは、キーワードcatchに続く括弧内に表示される例外宣言によって決まります。
try {
//protected code
} catch( ExceptionName e ) {
//code to handle ExceptionName exception
}
上記のコードは、 ExceptionName タイプの例外をキャッチします。 あなたがキャッチブロックがtryブロックでスローされる例外の任意のタイプを処理する必要があることを指定したい場合は、次のように例外宣言を囲む括弧の間に、省略記号…を配置する必要があります-
try {
//protected code
} catch(...) {
//code to handle any exception
}
以下はゼロ除算例外をスローする例で、catchブロックでキャッチします。
#include <iostream>
using namespace std;
double division(int a, int b) {
if( b == 0 ) {
throw "Division by zero condition!";
}
return (a/b);
}
int main () {
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << z << endl;
} catch (const char* msg) {
cerr << msg << endl;
}
return 0;
}
*const char* *型の例外を発生させているため、この例外をキャッチする際に、catchブロックでconst char *を使用する必要があります。 上記のコードをコンパイルして実行すると、次の結果が生成されます-
Division by zero condition!
C ++標準例外
C ++は、プログラムで使用できる <exception> で定義された標準例外のリストを提供します。 これらは、以下に示す親子クラス階層に配置されています-
ここに、上記の階層で言及された各例外の簡単な説明があります-
Sr.No | Exception & Description |
---|---|
1 |
std::exception すべての標準C ++例外の例外と親クラス。 |
2 |
std::bad_alloc これは new によってスローされます。 |
3 |
std::bad_cast これは dynamic_cast によってスローされます。 |
4 |
std::bad_exception これは、C ++プログラムで予期しない例外を処理するのに便利なデバイスです。 |
5 |
std::bad_typeid これは typeid によってスローされます。 |
6 |
std::logic_error コードを読み取ることで理論的に検出できる例外。 |
7 |
std::domain_error これは、数学的に無効なドメインが使用された場合にスローされる例外です。 |
8 |
std::invalid_argument これは無効な引数のためにスローされます。 |
9 |
std::length_error
|
10 |
std::out_of_range
|
11 |
std::runtime_error コードを読み取っても理論的に検出できない例外。 |
12 |
std::overflow_error これは、数学的なオーバーフローが発生した場合にスローされます。 |
13 |
std::range_error これは、範囲外の値を保存しようとしたときに発生します。 |
14 |
std::underflow_error これは、数学的なアンダーフローが発生した場合にスローされます。 |
新しい例外を定義する
- exception クラスの機能を継承およびオーバーライドすることにより、独自の例外を定義できます。 以下は、標準的な方法で独自の例外を実装するためにstd
- exceptionクラスを使用する方法を示す例です-
#include <iostream>
#include <exception>
using namespace std;
struct MyException : public exception {
const char * what () const throw () {
return "C++ Exception";
}
};
int main() {
try {
throw MyException();
} catch(MyException& e) {
std::cout << "MyException caught" << std::endl;
std::cout << e.what() << std::endl;
} catch(std::exception& e) {
//Other errors
}
}
これは、次の結果を生成します-
MyException caught
C++ Exception
ここで、* what()*は例外クラスによって提供されるパブリックメソッドであり、すべての子例外クラスによってオーバーライドされています。 これは、例外の原因を返します。