工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> C言語

C++例外処理をマスター:try、catch、throwの実践例

C++における例外処理とは

例外処理により、C++プログラムは予期せぬ実行時エラーから優雅に回復できます。エラーが発生すると、制御は特別なハンドラにジャンプし、どう対応するかを決定できます。

潜在的に問題のあるコードをtryブロックで囲み、それに1つ以上のcatch節を続けることで、プログラムに例外的状況を管理する明確なパスを与えます。

例外が投げられない場合、tryブロックは正常に実行され、ハンドラはバイパスされます。

このチュートリアルで学ぶ内容:

なぜ例外処理が必要か

例外処理にはいくつかの具体的なメリットがあります:

例外処理のキーワード

C++例外処理の骨格をなす3つのキーワード:

tryブロック内のコードは保護コードと呼ばれ、これが投げると対応するcatchブロックが実行されます。

構文

try {
    // 保護コード
} catch (Exception_Name exception1) {
    // exception1を処理
} catch (Exception_Name exception2) {
    // exception2を処理
}
// ... さらにcatchブロック

例1:vectorの範囲外アクセス

#include<iostream>
#include<vector>
using namespace std;
int main() {
    vector<int> vec;
    vec.push_back(0);
    vec.push_back(1);
    try {
        vec.at(2); // 範囲外
    } catch (exception& ex) {
        cout << "Exception occurred!" << endl;
    }
    return 0;
}

出力:

例外捕捉の出力

コードのスクリーンショット:

例1のソースコード

コード分解:

  1. I/Oとコンテナサポートのためiostreamとvectorをインクルード
  2. 完全修飾名を避けるためstd名前空間を使用
  3. vector<int>をインスタンス化し要素を追加
  4. tryブロック内でベクターの境界を超えた要素にアクセスを試行
  5. 標準std::exceptionを捕捉しメッセージ出力
  6. mainから返却

例2:ゼロ除算の処理

#include <iostream>
using namespace std;
double zeroDivision(int x, int y) {
    if (y == 0) {
        throw "Division by Zero!";
    }
    return static_cast<double>(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;
}

出力:

ゼロ除算例外の出力

コードのスクリーンショット:

例2のソースコード

コード分解:

  1. ゼロ除算時にC文字列を投げるzeroDivisionを定義
  2. 関数をtryブロック内で呼び出し結果を出力
  3. 文字列例外を捕捉しエラーメッセージを出力

C++標準例外

標準例外クラス階層図

標準ライブラリは<exception>で豊富な例外階層を宣言しています。よく使われるものを以下に示します:

例外説明
std::exceptionすべての標準例外の基底クラス
std::bad_allocnewの割り当て失敗時に投げられる
std::bad_castdynamic_castの失敗時に投げられる
std::bad_exception予期せぬ例外を通知するために使用
std::bad_typeidヌルな多態的型のglvalueにtypeid適用時に投げられる
std::logic_errorプログラマが検出可能なエラー
std::domain_error数学関数の無効な定義域
std::invalid_argument関数が無効な引数を受け取った
std::length_error過大な文字列作成の試み
std::out_of_rangevector::atでインデックスが範囲外の時に投げられる
std::runtime_error他のカテゴリで捕捉されない実行時エラー
std::overflow_error数学的オーバーフロー発生
std::range_error値が演算の範囲外
std::underflow_error数学的アンダーフロー発生

ユーザー定義例外

std::exception基底クラスを拡張してドメイン固有のエラー型を作成できます。what()をオーバーライドすると説明メッセージを提供できます。

例:カスタム例外

#include <iostream>
#include <exception>
using namespace std;
class NewException : public exception {
public:
    const char* what() const noexcept override {
        return "newException occurred";
    }
} newex;
int main() {
    try {
        throw newex;
    } catch (exception& ex) {
        cout << ex.what() << '\n';
    }
    return 0;
}

出力:

カスタム例外の出力

コードのスクリーンショット:

カスタム例外のソースコード

コード分解:

  1. NewExceptionをstd::exceptionから派生させwhat()をオーバーライド
  2. 投げる用のオブジェクトnewexをインスタンス化
  3. tryブロック内でnewexを投げる
  4. std::exceptionへの参照で捕捉しwhat()でメッセージ出力

ポイント

C言語

  1. C++コメント完全ガイド:読みやすく保守しやすいコードのためのベストプラクティス
  2. C++演算子を徹底解説:種類、例、サンプルプログラム付き
  3. C++ switch文をマスター:構文、使い方、実践例
  4. C++動的配列の確保をマスター:コード例付き実践ガイド
  5. C++構造体を実例で徹底解説
  6. C++のstd::listをマスターする:構文、関数、実践例
  7. C++ structとclassの違い:構文、特徴、使い分けのベストプラクティス
  8. 2021年版:Windows/macOS/Linux対応C++ IDEおすすめ15選(無料・有料)
  9. Python例外処理マスター:try、except、else、finallyを徹底解説
  10. Java例外ハンドリング完全攻略:try-catch、finally、throw、throws
  11. Java例外ハンドリング実践:try-catch-finallyとリソース管理