Z
ZHANK
现代 C++

异常处理

try/catch/throw、标准异常类、noexcept、RAII 保证

异常处理

C++ 没有 finally 块,但 RAII 让它不需要——析构函数会自动清理资源,即使发生了异常。

学完本章你将: 掌握 try/catch/throw、标准异常类、noexcept、RAII + 异常。


try / catch / throw

cpp
#include <iostream>
#include <stdexcept>

double divide(double a, double b) {
    if (b == 0) {
        throw std::runtime_error("除数不能为零!");
    }
    return a / b;
}

int main() {
    try {
        double result = divide(10, 0);
        std::cout << result << "\n";
    } catch (const std::runtime_error &e) {
        std::cout << "运行时错误:" << e.what() << "\n";
    } catch (const std::exception &e) {
        std::cout << "标准异常:" << e.what() << "\n";
    } catch (...) {
        std::cout << "未知异常\n";
    }
    return 0;
}

标准异常类层次

std::exception
 ├── std::logic_error       —— 程序逻辑错误
 │    ├── std::invalid_argument
 │    ├── std::out_of_range
 │    └── std::length_error
 └── std::runtime_error     —— 运行时错误
      ├── std::range_error
      ├── std::overflow_error
      └── std::system_error

noexcept —— 承诺不抛异常

cpp
void safe() noexcept {       // 承诺:不抛异常
    // 如果抛了 → std::terminate() 立即终止程序
}

// 移动构造应标记 noexcept(性能优化)
Buffer(Buffer &&other) noexcept : data(other.data) {
    other.data = nullptr;
}

RAII + 异常 = 完美搭配

cpp
void process() {
    auto p = std::make_unique<int>(42);  // RAII
    riskyOperation();                     // 可能抛异常
    // p 会自动释放——即使发生了异常
    // 不需要 try/finally!
}