エラー処理

例外とエラーハンドリング.

基本的なエラー処理

#include <iostream>
#include <stdexcept>

double divide(double a, double b) {
    if (b == 0) {
        throw std::invalid_argument("ゼロで割ることはできません");
    }
    return a / b;
}

int main() {
    try {
        std::cout << divide(10, 2) << std::endl;
        std::cout << divide(10, 0) << std::endl;
    } catch (const std::invalid_argument& e) {
        std::cout << "エラー: " << e.what() << std::endl;
    }
    
    return 0;
}

5
エラー: ゼロで割ることはできません

複数例外キャッチ

#include <iostream>
#include <stdexcept>
#include <string>

int stringToInt(const std::string& s) {
    if (s.empty()) {
        throw std::invalid_argument("文字列が空");
    }
    return std::stoi(s);  // std::invalid_argument や std::out_of_range を投げる
}

int main() {
    std::string inputs[] = {"123", "", "abc"};
    
    for (const auto& input : inputs) {
        try {
            int val = stringToInt(input);
            std::cout << input << " -> " << val << std::endl;
        } catch (const std::invalid_argument& e) {
            std::cout << "不正な引数: " << e.what() << std::endl;
        } catch (const std::out_of_range& e) {
            std::cout << "範囲外: " << e.what() << std::endl;
        } catch (const std::exception& e) {
            std::cout << "エラー: " << e.what() << std::endl;
        }
    }
    
    return 0;
}

123 -> 123
不正な引数: 文字列が空
範囲外: stoi

カスタム例外

#include <iostream>
#include <stdexcept>

class DatabaseException : public std::runtime_error {
public:
    DatabaseException(const std::string& msg) 
        : std::runtime_error("DB Error: " + msg) {}
};

void queryDatabase(int id) {
    if (id < 0) {
        throw DatabaseException("無効なID");
    }
    std::cout << "クエリ: ID=" << id << std::endl;
}

int main() {
    try {
        queryDatabase(5);
        queryDatabase(-1);
    } catch (const DatabaseException& e) {
        std::cout << e.what() << std::endl;
    }
    
    return 0;
}

クエリ: ID=5
DB Error: 無効なID

ポイント

  • 例外で異常系を報告
  • try-catch で捕捉
  • カスタム例外で細かく制御