捕获抛出的异常与将参数传递给函数完全不同。有相似之处,但也有细微的差别。
3个主要区别是:
- 异常总是至少被复制一次(根本不可能避免)
catch
子句按照声明的顺序进行检查(不是最合适的)
- 它们受到较少形式的类型转换:
- 基于继承的覆盖,
- 从类型化指针到非类型化指针的转换(
const void*
捕获任何指针)
不允许任何其他类型的转换(例如int
todouble
或隐式const char*
to string
- 您的示例)。
关于评论中的问题
假设存在层次结构:
class Base {};
class Derived: public Base {};
class Base2 {};
class Leaf: public Derived, public Base2 {};
现在根据catch
子句的顺序,将执行适当的块。
try {
cout << "Trying ..." << endl;
throw Leaf();
} catch (Base& b) {
cout << "In Base&";
} catch (Base2& m) {
cout << "In Base2&"; //unreachable due to Base&
} catch (Derived& d) {
cout << "In Derived&"; // unreachable due to Base& and Base2&
}
如果您切换Base
并Base2
捕获订单,您会注意到不同的行为。如果Leaf
从 私下继承Base2
,那么catch Base2&
无论放在哪里都无法访问(假设我们抛出 a Leaf
)
通常很简单:顺序很重要。