异常处理
内容简介
异常用于处理无法在当前函数中正常解决的错误。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 强相关,后续学习智能指针、容器时会反复遇到。