异常处理

内容简介

异常用于处理无法在当前函数中正常解决的错误。C++ 通过 throw 抛出异常,try/catch 捕获异常。异常适合表达构造失败、资源获取失败、解析失败等错误。

用法

#include <stdexcept>
 
double divide(double a, double b)
{
    if (b == 0.0) {
        throw std::invalid_argument("division by zero");
    }
    return a / b;
}
 
int main()
{
    try {
        double result = divide(10, 0);
        std::cout << result << std::endl;
    } catch (const std::invalid_argument& e) {
        std::cerr << e.what() << std::endl;
    }
}

最佳代码实践

  • 抛出标准异常类型或自定义异常类型,不要抛字符串字面量。
  • 捕获异常时优先使用 const T&,避免切片和拷贝。
  • 只捕获自己能处理的异常;不能处理就让它继续向上传播。
  • 析构函数中不要抛异常。
  • 使用 RAII 管理资源,保证异常发生时资源也能自动释放。

错误用法

throw "error";  // 不推荐:类型信息弱,处理不统一
try {
    risky();
} catch (...) {
    // 错误倾向:吞掉所有异常却不处理,会掩盖问题
}
catch (std::exception e) {  // 错误倾向:按值捕获会发生切片
    std::cout << e.what();
}

注意事项

  • 异常不是普通流程控制,不要用异常替代 if
  • C 接口通常不使用 C++ 异常,跨 C ABI 边界抛异常风险很高。
  • 异常安全和 RAII 强相关,后续学习智能指针、容器时会反复遇到。

相关:cpp异常处理案例RAII

学习路径