网上看了一篇类似的分析,仔细看了一下写的不错,现在把代码引用一下:
try
{
try
{
// 抛出一个异常对象
throw MyException("ex_obj1");
}
// 异常对象按值传递
catch(MyException e)
{
cout<<endl<<"捕获到一个MyException*类型的异常,名称为:"<<e.GetName()<<endl;
cout<<"下面重新抛出异常"<<endl<<endl;
// 异常对象重新被抛出
throw;
}
}
// 异常对象再次按值传递
catch(MyException e)
{
cout<<endl<<"捕获到一个MyException*类型的异常,名称为:"<<e.GetName()<<endl;
}
这个地方异常作了四次构造,这四次构造分别称为obj1,obj2,obj3,obj4。逐一道来。
throw MyException("ex_obj1");看看这段代码。好像有一句话说,捕获的所有异常,永远不是异常对象本身。为什么这么说?MyException("ex_obj1")是构造了一个局部变量,但是这个局部变量被throw出去后会生成一个临时变量,我们所catch到的不是这个对象本身,而是这个临时对象。这个临时对象本身并没有什么,但却非常重要。因为rethrow是这个临时对象,而不是用值传递生成的新对象。所以用值传递的方式,不能将修改带到下一个catch块。后面两个catch就是obj3和obj4了,以后就不用想什么,对obj3和obj4所做的任何动作不会带到下一步,因为重新抛出的是obj2。
其实异常抛出很简单的,用引用传递就可以了。使用引用传递的好处就是每次catch都可以做点小动作。呵呵!