异常仅用于处理错误
不要滥用异常。
不要盲目catch,不能处理的异常应继续向上传播
避免在不宜抛异常的地方抛出异常
构造异常的操作本身不应抛出异常,
// // 如果exp本身抛出异常,这一句实际抛出的就是exp抛出的异常,而非程序员原本想抛出的异常,confusing
throw exp;
下面特定的函数不宜抛异常:
- 全局变量和线程局部变量的构造函数:全局变量构造时,main函数还没有执行,无法捕获这个异常
- 析构函数
- delete操作符
- 移动构造函数
- 移动赋值操作符
- swap函数
4、5、6会被标准库调用,而其调用时不期望异常抛出。在这些地方抛异常将无法处理、或破坏标准库的某些性质。
异常的抛出与捕获
- 只使用std::exception的派生类实例作为异常对象,不要使用基本类型
- 抛异常时,抛对象本身而非指针,否则会造成回收责任不明确,简而言之new的异常对象谁负责delete?
- 以左值引用的形式捕获异常,如果按值捕获异常的基类,会导致对象被切片。因为只有引用和指针有动态绑定,按值传递会导致类型转换(派生类向基类隐式转换),导致对象被切片。
- try-catch语句有多个catch子句时,catch的顺序应该是先捕获派生类,后捕获基类