キャッチオールハンドラ
CoddyのC++ジャーニー「論理と制御フロー」セクションの一部。レッスン 52/56。
プログラムでは、想定していた特定の例外型に当てはまらない予期しないエラーが発生することがあります。包括的なハンドラー catch(...) は、より具体的な catch ブロックで処理されなかった例外をすべて捕捉する安全網となります。
すべての例外を捕捉するハンドラーは、特定の例外型を指定する代わりに3つのドット (...) を使用します。C++は順番にチェックするため、ほかのすべての catch ブロックの後に配置する必要があります。
try {
// さまざまな例外をスローする可能性があるコード
} catch (std::invalid_argument& e) {
std::cout << "Invalid input!" << std::endl;
} catch (std::out_of_range& e) {
std::cout << "Number too large!" << std::endl;
} catch (...) {
std::cout << "An unexpected error occurred!" << std::endl;
}catch-allハンドラーは、前のブロックで捕捉されなかったあらゆる例外型に対するフォールバックとして機能します。これは、予期していない例外がスローされる可能性のあるコードを扱う際に特に役立ち、予期しないエラーによってプログラムがクラッシュするのを防ぎます。
catch-all ブロックでは例外の具体的な詳細にアクセスできませんが、汎用的なエラーメッセージを表示し、クリーンアップ処理を実行してプログラムがスムーズに動作し続けるようにすることはできます。
チャレンジ
簡単複数のcatchブロックとcatch-allハンドラーを使って、包括的な例外処理を実演するプログラムを作成してください。この課題では、特定の例外型と、あらかじめ定義されたカテゴリに当てはまらない予期しないエラーの両方を処理する方法についての理解を確認します。
次の入力が与えられます。
- 実行するテストの種類を表す文字列
testType("string_convert"、"math_operation"、"array_access"、または"unknown_error") - 操作の主なデータとして使われる文字列
value1 - 一部の操作で副次的なデータとして使われる文字列
value2
プログラムでは、次の処理を行ってください。
- 3つの文字列パラメーターを受け取る関数
performTestを作成する - 関数内でif-else構造を使い、テストの種類ごとに処理する:
- testTypeが
"string_convert"の場合:std::stoiを使ってvalue1を整数に変換し、出力する - testTypeが
"math_operation"の場合:std::stoiを使ってvalue1とvalue2の両方を整数に変換し、value1をvalue2で割って結果を出力する - testTypeが
"array_access"の場合:文字列"Programming"を作成し、std::stoiを使ってvalue1を整数のインデックスに変換した後、str.at(index)を使ってそのインデックスの文字にアクセスし、出力する。.at()メソッドはインデックスが無効な場合に自動的にstd::out_of_rangeをスローします。手動で範囲チェックを行う必要はありません - testTypeが
"unknown_error"の場合:整数値999をスローする - main関数で、
tryブロック内からperformTestを呼び出す - 例外を次の正確な順序で処理する複数の
catchブロックを使う: - 最初:無効な文字列から数値への変換に対する
std::invalid_argument& - 2番目:大きすぎる数値、または文字列インデックスが範囲外の場合に対する
std::out_of_range& - 3番目:その他すべての例外型を処理するcatch-allハンドラーとしての
catch(...)
次の出力形式を厳密に使用してください。
操作が成功した場合:
Success: [result_value]例外の種類ごとの場合:
Invalid argument caught
Out of range caught
Unknown exception caughtC++はcatchブロックを順番に確認するため、catch-allハンドラーのcatch(...)は最後に配置する必要があります。このハンドラーは、それ以前の特定のcatchブロックで処理されなかったすべての例外型を捕捉します。これには、"unknown_error"の場合にスローされる整数例外も含まれます。catch-allハンドラーは、既知の例外型を個別に処理できるようにしながら、予期しないエラーに備える安全網となります。
自分で試してみよう
#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;
// TODO: ここにコードを書いて、performTest 関数を作成する
int main() {
// 入力を読み込む
string testType;
string value1;
string value2;
cin >> testType;
cin >> value1;
cin >> value2;
// TODO: 以下にコードを書いて、try-catch ブロックを実装し、performTest を呼び出す
return 0;
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
論理と制御フローのすべてのレッスン
自分で練習してみよう: C++オンラインコンパイラ