Menu
Coddy logo textTech

キャッチオールハンドラ

CoddyのC++ジャーニー「論理と制御フロー」セクションの一部 — レッスン 52/56。

時として、プログラムは、想定していた特定の例外タイプに当てはまらない予期しないエラーに遭遇することがあります。キャッチオールハンドラーである catch(...) は、より具体的な catch ブロックで処理されなかったあらゆる例外をキャッチするセーフティネットを提供します。

キャッチオールハンドラは、特定の例外型を指定する代わりに、3つのドット (...) を使用します。C++は catch ブロックを順番にチェックするため、これは他のすべての 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;
}

キャッチオールハンドラは、前のブロックでキャッチされなかったあらゆる例外タイプに対するフォールバックとして機能します。これは、予期しない例外をスローする可能性のあるコードを扱う場合に特に便利で、予期しないエラーによってプログラムがクラッシュするのを防ぐことができます。

キャッチオールブロックでは例外の特定の詳細にアクセスすることはできませんが、一般的なエラーメッセージを表示したり、プログラムをスムーズに実行し続けるためのクリーンアップ操作を実行したりすることは可能です。

challenge icon

チャレンジ

簡単

キャッチオールハンドラーを含む複数の catch ブロックを使用して、包括的な例外処理を実証するプログラムを作成してください。このチャレンジでは、特定の例外タイプと、定義済みのカテゴリに当てはまらない予期しないエラーの両方を処理する方法についての理解をテストします。

以下の入力が提供されます:

  • 実行するテストのタイプを表す文字列 testType ("string_convert", "math_operation", "array_access", または "unknown_error")
  • 操作の主要データとして使用される文字列 value1
  • 一部の操作で二次データとして使用される文字列 value2

プログラムは以下の手順で行う必要があります:

  1. 3つの文字列パラメータを受け取る performTest という名前の関数を作成します
  2. 関数内で、if-else 構造を使用して異なるテストタイプを処理します:
  3. testType が "string_convert" の場合:std::stoi を使用して value1 を整数に変換し、それを表示します
  4. testType が "math_operation" の場合:std::stoi を使用して value1 と value2 の両方を整数に変換し、value1 を value2 で割って結果を表示します
  5. testType が "array_access" の場合:文字列 "Programming" を作成し、std::stoi を使用して value1 を整数のインデックスに変換し、str.at(index) を使用してそのインデックスの文字にアクセスして表示します。.at() メソッドは、インデックスが無効な場合に自動的に std::out_of_range をスローします。手動の境界チェックは不要です
  6. testType が "unknown_error" の場合:整数値 999 をスローします
  7. main 関数内で、try ブロックの中で performTest を呼び出します
  8. 以下の正確な順序で複数の catch ブロックを使用して例外を処理します:
  9. 1番目:無効な文字列から数値への変換のための std::invalid_argument&
  10. 2番目:数値が大きすぎる場合や文字列のインデックスが範囲外の場合のための std::out_of_range&
  11. 3番目:その他の例外タイプのためのキャッチオールハンドラーとしての catch(...)

以下の正確な出力形式を使用してください:

操作が成功した場合:

Success: [result_value]

異なる例外タイプの場合:

Invalid argument caught
Out of range caught
Unknown exception caught

C++ は catch ブロックを順番にチェックするため、キャッチオールハンドラー catch(...) は最後に配置する必要があることに注意してください。このハンドラーは、"unknown_error" ケースでスローされる整数の例外を含め、前の特定の catch ブロックで処理されなかったあらゆる例外タイプをキャッチします。キャッチオールハンドラーは、既知の例外タイプに対して特定の処理を可能にしながら、予期しないエラーに対するセーフティネットを提供します。

チートシート

すべてをキャッチするハンドラ catch(...) は、特定の catch ブロックで処理されなかった例外をすべて捕捉するセーフティネットを提供します。

このキャッチオールハンドラは3つのドット (...) を使用し、C++は catch ブロックを順番にチェックするため、必ず他のすべての catch ブロックの後に配置する必要があります。

try {
    // Code that might throw various exceptions
} 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;
}

キャッチオールハンドラは、前のブロックで捕捉されなかったあらゆる例外タイプに対するフォールバックとして機能します。キャッチオールブロック内では特定の例外の詳細にアクセスすることはできませんが、一般的なエラーメッセージを表示したり、クリーンアップ操作を実行したりすることができます。

自分で試してみよう

#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;
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

論理と制御フローのすべてのレッスン