在C++中,异常抛出规则的核心要点是:通过throw抛出异常对象,异常类型可以是任意可拷贝类型,但推荐使用标准异常类或自定义异常类。抛出异常会立即终止当前函数执行,并通过栈展开机制寻找匹配的catch块进行处理。
-
throw表达式用法
- 使用throw关键字后接异常对象:
throw 42;
或throw std::runtime_error("error");
- 可以抛出基本类型(int、char等)、对象、字符串字面量,但对象必须可拷贝
- 抛出指针时需注意内存管理,通常应避免抛出动态分配对象的指针
- 使用throw关键字后接异常对象:
-
异常类型选择原则
- 优先使用
<stdexcept>
中的标准异常类(如logic_error、runtime_error) - 自定义异常类应继承自std::exception,并重写what()方法
- 异常类应包含足够诊断信息,例如错误代码、位置描述等
- 优先使用
-
栈展开机制
- 抛出异常后,编译器按调用链反向查找catch块
- 自动调用局部对象的析构函数(RAII原则)
- 若未找到匹配的catch块,调用std::terminate终止程序
-
特殊场景处理
- 不允许在析构函数中抛出异常,可能导致双重异常
- noexcept函数中抛出异常会直接触发std::terminate
- 构造函数抛出异常时,已构造的成员会自动析构
-
性能与安全建议
- 异常处理比正常返回消耗更多资源,仅用于异常情况
- 确保异常安全:基本保证、强保证或不抛保证
- 跨模块边界时需统一异常类型约定
合理使用异常机制能显著提升代码健壮性,但要注意避免滥用异常处理常规流程控制。建议结合智能指针和RAII技术管理资源,同时为关键操作提供无异常版本(如std::vector::at()和operator[]的区别)。复杂系统应明确定义异常层次结构,并通过单元测试验证异常处理路径。