C++ 例外処理: Try、Catch、throw の例

C++ の例外処理とは何ですか?

C++ の例外処理は、実行時エラーなどの予期しない状況を処理する方法を提供します。 したがって、予期しない状況が発生するたびに、プログラムの制御はハンドラーと呼ばれる特別な関数に転送されます。

例外をキャッチするには、コードの一部のセクションを例外検査下に置きます。 コードのセクションは try-catch ブロック内に配置されます。

コードのそのセクション内で例外的な状況が発生すると、例外がスローされます。 次に、例外ハンドラーがプログラムの制御を引き継ぎます。

例外的な状況が発生しない場合、コードは通常どおり実行されます。 ハンドラーは無視されます。

この C++ チュートリアルでは、次のことを学習します。

なぜ例外処理なのか?

C++ で例外処理を使用する理由は次のとおりです。

  • エラー処理コードを通常のコードから分離します。 コードはより読みやすくなり、保守が容易になります。
  • 関数は、選択した例外を処理できます。 関数が多くの例外をスローしたとしても、処理できるのは一部だけです。 呼び出し元は、キャッチされなかった例外を処理します。

例外処理のキーワード

C++ での例外処理は、次の XNUMX つのキーワードを中心に展開します。

  • 投げる– プログラムで問題が発生すると、例外がスローされます。 throw キーワードは、プログラムによるスローの実行に役立ちます。
  • キャッチ– プログラムは例外ハンドラーを使用して例外をキャッチします。 これは、問題を処理する必要があるプログラムのセクションに追加されます。 これは、catch キーワードを使用して行われます。
  • 試します– try ブロックは、特定の例外がアクティブになるコード ブロックを識別します。 その後に XNUMX つ以上の catch ブロックが続く必要があります。

コード ブロックが例外を発生させるとします。 例外は、try および catch キーワードを使用したメソッドによってキャッチされます。 try/catch ブロックは、例外をスローする可能性のあるコードを囲む必要があります。 このようなコードは、保護されたコードとして知られています。

構文

try/catch は次の構文を使用します。

try {
   // the protected code
} catch( Exception_Name exception1 ) {
   // catch block
} catch( Exception_Name exception2 ) {
   // catch block
} catch( Exception_Name exceptionN ) {
   // catch block
}
  • try ステートメントは XNUMX つですが、catch ステートメントは多数持つことができます。
  • ExceptionName は、キャッチされる例外の名前です。
  • 例外 1、例外 2、および例外 N は、例外を参照するために定義した名前です。

例1:

#include<iostream>
#include<vector>
using namespace std;

int main() {
	vector<int> vec;
	vec.push_back(0);	
	vec.push_back(1);	
	// access the third element, which doesn't exist
	try
	{
		vec.at(2);		
	}
	catch (exception& ex)
	{
		cout << "Exception occurred!" << endl;
	}
	return 0;
}

出力:

例外処理のキーワード

コードのスクリーンショットは次のとおりです。

例外処理のキーワード

コードの説明:

  1. iostream ヘッダー ファイルをプログラムにインクルードして、そのヘッダー ファイルを使用します。 機能.
  2. その機能を使用するには、プログラムにベクター ヘッダー ファイルをインクルードします。
  3. std 名前空間を呼び出さずに、プログラムのクラスに組み込みます。
  4. main() 関数を呼び出します。 プログラム ロジックは本体内に追加する必要があります。
  5. 整数データを格納するために vec という名前のベクトルを作成します。
  6. 要素 0 を vec という名前のベクトルに追加します。
  7. 要素 1 を vec という名前のベクトルに追加します。
  8. コメント。 によってスキップされます C++コンパイラ.
  9. 例外をキャッチするには、try ステートメントを使用します。 { は、try/catch ブロックの本体の始まりを示します。 ボディ内に追加されたコードが保護されたコードになります。
  10. vec という名前のベクトルのインデックス 2 (XNUMX 番目の要素) に格納されている要素にアクセスしてみます。 この要素は存在しません。
  11. try/catch ブロックの本体の終わり。
  12. 例外をキャッチします。 返されたエラー メッセージは変数 ex に格納されます。
  13. 例外がキャッチされた場合は、コンソールにメッセージを出力します。
  14. キャッチブロック本体の端。
  15. プログラムは、実行が成功すると値を返す必要があります。
  16. main() 関数本体の終わり。

例2:

#include <iostream>
using namespace std;
double zeroDivision(int x, int y) {

	if (y == 0) {
		throw "Division by Zero!";
	}
	return (x / y);
}

int main() {
	int a = 11;
	int b = 0;
	double c = 0;

	try {
		c = zeroDivision(a, b);
		cout << c << endl;
	}
	catch (const char* message) {
		cerr << message << endl;
	}
	return 0;
}

出力:

例外処理のキーワード

コードのスクリーンショットは次のとおりです。

例外処理のキーワード

コードの説明:

  1. iostream ヘッダー ファイルをプログラムにインクルードして、その機能を使用します。
  2. std 名前空間を呼び出さずに、プログラムのクラスに組み込みます。
  3. XNUMX つの整数引数 x と y を取る、zeroDivision という名前の関数を作成します。 この関数は double の結果を返す必要があります。
  4. if ステートメントを使用して、変数引数 y の値が 0 であるかどうかを確認します。{ は if 本体の始まりを示します。
  5. y が 0 の場合に返される/スローされるメッセージ。
  6. if ステートメントの本文の終わり。
  7. zeroDivision 関数は x/y の値を返す必要があります。
  8. zeroDivision 関数の本体の終わり。
  9. main() メソッドを呼び出します。 { はこのメソッドの始まりを示します。
  10. 整数変数を宣言し、値 11 を割り当てます。
  11. 整数変数 b を宣言し、値 0 を割り当てます。
  12. double 変数 c を宣言し、値 0 を割り当てます。
  13. 例外をキャッチするには、try ステートメントを使用します。 { は、try/catch ブロックの本体の始まりを示します。 ボディ内に追加されたコードが保護されたコードになります。
  14. zeroDivision 関数を呼び出し、引数 a と b、つまり 11 と 0 に渡します。この演算の結果は変数 c に格納されます。
  15. 変数 c の値をコンソールに出力します。
  16. try/catch ブロックの本体の終わり。
  17. 例外をキャッチします。 返されたエラー メッセージは変数 message に格納されます。
  18. 返されたエラー メッセージをコンソールに出力します。
  19. キャッチブロック本体の端。
  20. プログラムは、実行が成功すると値を返す必要があります。
  21. main() 関数本体の終わり。

C++ 標準例外

C++ 標準例外

C++ には、以下で定義された標準例外のリストが付属しています。 クラス。 これらについては以下で説明します。

例外 Description
std::例外 これは例外であり、すべての標準 C++ 例外の親クラスです。
std::bad_alloc この例外は、新しいキーワードによってスローされます。
std::bad_cast これは、dynamic_cast によってスローされる例外です。
std::bad_Exception C++ プログラムで予期しない例外を処理するための便利なデバイス。
std::bad_typeid typeid によってスローされる例外。
std::logic_error この例外は理論的にはコードを読み取ることで検出できます。
std::domain_error これは、数学的に無効なドメインを使用した後にスローされる例外です。
std::invalid_argument 無効な引数を使用した場合にスローされる例外。
std::length_error 大きな std::string を作成した後にスローされる例外。
std::範囲外 at メソッドでスローされます。
std :: runtime_error これはコードを読んでも検出できない例外です。
std::overflow_error この例外は、数学的オーバーフローが発生した後にスローされます。
std::range_error この例外は、範囲外の値を保存しようとするとスローされます。
std::underflow_error 数学的アンダーフローの発生後にスローされる例外。

ユーザー定義の例外

C++ std::Exception クラスを使用すると、例外としてスローできるオブジェクトを定義できます。 このクラスはヘッダ。 このクラスは、what という名前の仮想メンバー関数を提供します。

この関数は、char * 型の NULL で終わる文字シーケンスを返します。 派生クラスでこれを上書きして、例外の説明を含めることができます。

例:

#include <iostream>
#include <exception>
using namespace std;

class newException : public exception
{
	virtual const char* what() const throw()
	{
		return "newException occurred";
	}
} newex;

int main() {

	try {
		throw newex;
		}
	catch (exception& ex) {
		cout << ex.what() << '\n';
	}
	return 0;	
}

出力:

ユーザー定義の例外

コードのスクリーンショットは次のとおりです。

ユーザー定義の例外

コードの説明:

  1. iostream ヘッダー ファイルをプログラムに含めます。 エラーが発生することなくその関数を使用してみます。
  2. 例外ヘッダー ファイルをプログラムに含めます。 エラーなくその関数をどのように使用していきます。
  3. プログラムに std 名前空間を含めると、そのクラスを呼び出さずに使用できます。
  4. newException という名前の新しいクラスを作成します。 このクラスはC++の例外クラスを継承しています。
  5. クラス本体の始まり。
  6. 例外ヘッダー ファイルで定義されている仮想メンバー関数 what() を上書きします。 次に、独自の例外である新しい例外について説明します。
  7. 新しい例外の定義を開始します。
  8. 新しい例外がキャッチされた場合に返されるメッセージ。
  9. 新しい例外の定義の終わり。
  10. newException クラスの本体の終わり。 newex は新しい例外をキャッチするために使用される名前で、その後 newException が呼び出されます。
  11. main() 関数を呼び出します。 プログラム ロジックは本体内に追加する必要があります。 { は本体の始まりを示します。
  12. try ステートメントを使用して、例外をマークする必要があるコードをマークします。 { は、try/catch ブロックの本体の始まりを示します。 これで囲まれたコードが保護されます。
  13. newex 例外がキャッチされた場合はスローします。
  14. トライ本体の終了。
  15. 例外をキャッチするには、catch ステートメントを使用します。 例外エラー メッセージは変数 ex に格納されます。
  16. 例外エラー メッセージをコンソールに出力します。
  17. catch ステートメントの本文の終わり。
  18. プログラムが正常に実行された場合、プログラムは値を返す必要があります。
  19. main() 関数の本体の終わり。

まとめ

  • C++ の例外処理を使用すると、実行時エラーを処理できます。
  • 実行時エラーは、プログラムの実行中に発生するエラーです。
  • 例外処理は、プログラム内の予期せぬ状況に対処するのに役立ちます。
  • 予期せぬ状況が発生した場合、プログラムの制御はハンドラーに移されます。
  • 例外をキャッチするには、try-catch ブロックの下にコードのセクションを配置します。
  • throw キーワードは、プログラムが例外をスローするのに役立ち、プログラムによる問題の処理に役立ちます。
  • try キーワードは、特定の例外がアクティブになるコード ブロックを識別するのに役立ちます。
  • 例外ヘッダー ファイルの what() 関数を上書きして、例外を定義できます。