16.3.2 异常处理机制与函数的不同
异常处理机制与函数的不同主要体现在以下3个方面。
1.堆栈引退
代码16.11 直观地体现了两者的不同,对函数来说,执行结束后只有本函数中定义的局部变量和类对象被撤销,但对throw-catch异常处理机制来说,从throw语句到try语句之间所有的局部变量和类对象都会被自动撤销。
2.控制权返回
函数执行结束后,控制权交回给上级调用函数,但throw语句将控制权向上返回到第一个这样的函数,即包含能捕获相应异常的try-catch组合,这可能一下跨越了多个调用层次,如以下代码所示。
void fun1() { throw"error";//fun1函数中抛出异常error } void fun2() { fun1();//fun2函数中调用fun1 } void fun3() { fun2();//fun3函数中调用fun2 } void fun4() { try { fun3(); } catch(const char*s) { cout<<s<<endl; } }
执行到fun1函数中的throw语句时,控制权将直接返回到fun4函数。
3.catch块的参数
引发异常时,编译器总是创建一个临时副本,即使异常规范和catch块参数中指定的是引用。这是因为抛出的对象在throw语句执行时,控制权返回后就被撤销了。那么既然throw语句将生成副本,为什么还要在catch块参数中使用引用呢?这并非出于效率的考虑,而是通过引用与虚函数机制,使得基类引用可以调用派生类对象的成员函数。