条款12:了解[掷出一个exception]与[传递一个参数]或[调用一个虚函数]之间的差异
这个地方我在我先前关于异常的部分论述的比较清楚,这里只是写一些以前不曾写过的细节。第一个要点是异常抛出的如果是一个指针,那么C++没有义务顾及指针指向的地址,那么指针指向的内容需要用户负责,也就是说程序员需要保证指针指向的内容有效。其他方式,无论是值传递还是引用传递都是会自动复制一个对象副本,因为需要保证对象没有出生命域,依然存在。所以传递参数和抛出异常在同样情况下速度是不同的。第二,异常的抛出在以值传递和引用传递的时候,考虑抛出对象都是以对象的静态型别,所以特别需要注意的是不要对象切片了。
考虑两段代码:
catch(A& a)
{
throw;
}
catch(A& a)
{
Throw a;
}
这两段代码的意义是不同的。上面代表异常的Rethrow,对象是不拷贝的。而下面只是对象的抛出,这时候会发生对象拷贝,也就是说抛出的是副本。
还有需要注意的是,对异常捕获不要去期待隐式转换。因为异常捕获只支持两种转换,一种是继承架构中的exception转换,一种是有型指针向void指针的转换。
最后就是catch之句的顺序,通常顺序要是从小范围到大范围,从派生类到基类。