⚡ 为什么需要异常处理?
当函数遇到无法处理的错误时(如除零、文件不存在),传统返回错误码的方式需要逐层检查,导致代码耦合。异常处理允许错误直接"跳转"到处理模块:
cpp
double safeDivide(double a, double b) {
if (b == 0) throw std::runtime_error("除数不能为0"); // 抛出
return a / b;
}
🔍 核心三件套使用
1. throw
- 抛出异常
- 可抛出任意类型(但推荐标准异常类)
cpp
throw 42; // 基本类型(不推荐)
throw std::out_of_range("索引越界"); // 标准异常类✅
2. try/catch
- 捕获并处理
catch
按顺序匹配类型,支持常量引用捕获
cpp
try {
safeDivide(10, 0);
}
catch (const std::runtime_error& e) { // 引用捕获避免拷贝
std::cout << "数学错误: " << e.what() << std::endl;
}
catch (...) { // 兜底捕获所有异常
std::cout << "未知错误" << std::endl;
}
🚫 常见陷阱规避
- 避免捕获基类在前
cpp
catch (const std::exception& e) { /*...*/ } // 捕获所有派生类
catch (const std::runtime_error& e) { ... } // ❌ 永远不会被执行!
- 不要忽略异常
空catch
块会导致静默失败:
cpp
try { /* 可能出错的操作 */ }
catch (...) {} // ❌ 危险!隐藏了错误
推荐:C++学习一站式分享