15.3
15.3 异常
调用abort()
返回错误码
异常机制
try {}
catch (异常类型) {}
throw 异常类型的变量/对象;
捕获所有异常:
catch (...) {}
将对象作为异常类型
异常规范和C++11
栈解退
try块中的函数调用了引发异常的函数, 程序将从引发异常的函数跳转的try块和处理程序的函数, 涉及到栈解退。
栈解退将会释放throw到达try块前栈中所有的函数和对象(调用析构函数)。
其他异常特性
throw 引发的异常是临时拷贝。
捕获父类的引用, 可以将子类的也一起捕获, 所以父类应该放在最后。
exception类
异常、类和继承
异常何时会迷失方向
未捕获异常:
terminate()-->abort()
set_terminate()修改terminate调用的函数
意外异常:
unexpected()-->terminated()-->abort()
set_unexpected()修改unexpected()调用的函数
意外异常较为复杂。。如果unexpected()调用的函数引发了一个新的异常... ... P640
有关异常的注意事项
缺点:
使用异常增加程序代码, 降低程序运行速度, 异常规范不适用于模板, 异常和动态内存分配并不总能协同工作。
动态内存分配和异常:
栈解退时, 栈中的自动变量会被释放, 但是动态分配的内存将不会被释放。--内存泄漏。
可以在引发异常的函数中捕获该异常, 然后再catch块中包含一些清理代码, 然后重新引发该异常:
double *ar = new double[n];
try
{
if (oh_no)
throw exception();
}
catch (exception &ex)
{
delete [] arr;
throw;
}
但是, 这件共增加疏忽和产生其他错误的机会。另一种解决办法:第十六章将讨论只能指针模板。