当你写一个catch子句时,必须确定让异常通过何种方式传递到catch子句里。你可以有三个选择:与你给函数传递参数一样,通过指针(by pointer),通过传值(by value)或通过引用(by reference)。
我们首先讨论通过指针方式捕获异常(catch by pointer)。从throw处传递一个异常到catch子句是一个缓慢的过程,在理论上这种方法的实现对于这个过程来说是效率最高的。因为在传递异常信息时,只有采用通过指针抛出异常的方法才能够做到不拷贝对象,例如:
class exception { ... }; // 来自标准C++库(STL)
// 中的异常类层次
void someFunction()
{
static exception ex; // 异常对象
...
throw &ex; // 抛出一个指针,指向ex
...
}
void doSomething()
{
try {
someFunction(); // 抛出一个 exception*
}
catch (exception *ex) { // 捕获 exception*;
... // 没有对象被拷贝
}
}
这看上去很不错,但是实际情况却不是这样。为了能让程序正常运行,程序员定义异常对象时必须确保当程序控制权离开抛出指针的函数后,对象还能够继续生存。全局与静态对象都能够做到这一点,但是程序员很容易忘记这个约束。如果真是如此的话,他们会这样写代码:
void someFunction()
{
exception ex; // 局部异常对象;
// 当退出函数的生存空间时
// 这个对象将被释放。
...
throw &ex; // 抛出一个指针,指向
... // 已被释放的对象
}
这简直糟糕透了,因为处理这个异常的catch子句接受到的指针,其指向的对象已经不再存在。