函数参数和exceptions的传递方式有3种:by value by reference by pointer
当我们调用的是一个函数,控制权最终会回到调用端。但当你抛出一个异常,控制权不会再回来抛出端。
istream operator>>(istream& s, Widget& w);
void passAndThrowWidget()
{
Widget localWidget;
cin>>localWidget;
throw localWidget;
}
C++特别声明,一个对象被抛出作为exception时,总是会发生复制。
void passAndThrowWidget()
{
static Widget localWidget;
cin>>localWidget;
throw localWidget;
}
若此exception以by reference方式捕捉,catch端还是不可能修改localWidget,只能修改localWidget的副本。注定后者比前者慢,因为有一个复制的过程。
class Widget{...};
class SpecialWidget : public Widget{ ... };
void passAndThrowWidget()
{
SpecialWidget localSpecialWidget;
....
Widget& rw = localSpecialWidget;//rw代表一个SpecialWidget
throw rw;//抛出一个类型为Widget的exception
}
C++中的复制动作总是永远是以对象的静态类型为本。
catch( Widget& w)
{
...
throw;
}
catch( Widget& w)
{
.....
throw w;
}
前者 重新抛出当前的exception,后者抛出的是当前exception的副本。
第一语句块重新抛出当前的exception,不论其类型为何。更明确地说如果最初抛出的exception的类型是SpecialWidget,第一语句块会传播一个SpecialWidget
exception---甚至虽然w的静态类型是widget.这是因为当此exception被重新抛出时,并没有发生复制行为。第二catch语句块则抛出一个新的exception,其类型总是
widget,因为那是w的静态类型。
函数调用过程中将一个临时对象传递给一个non-const-reference参数是不允许的。但对exceptions则属合法。
虚函数采用的是best fit策略,而exception处理机制确是first fit。
总结,3个主要的差异:
1、是否复制;
2、类型转换;
3、匹配顺序;
More Effective C++---12th