抛出一个异常
C++ 是一个难学易用的语言!难学一方面在于其广博,因此我选择用笔记的形式精简出一些有用的条款。
# 函数与异常的参数
虽然函数的参数声明与 catch
子句中声明参数看起来几乎没什么区别,但其实存在这巨大的差异。
- 调用函数时,程序的控制权会回到函数调用处;但抛出异常时,控制权永远不会回到抛出异常的地方
- 对象作为参数传递给函数时不一定需要拷贝;但异常对象在传递时总是进行拷贝构造,当通过传值方式捕获时,异常对象被拷贝了两次,一个是所有异常都必须建立的临时对象,另一个则是传值方式决定的拷贝
- 对象作为参数传递给函数与作为异常被抛出相比,前者类型转换比后者多,后者只有两种形式:继承类与基类,类型化指针(typed pointer)与无类型指针(untyped pointer)
catch
子句进行异常匹配的顺序是他们在源代码中出现的顺序,而一个对象调用虚函数时,总选择最佳匹配的类,与源代码顺序无关
注意,
用 throw
总是抛出当前的异常,即不改变传递出去的异常类型,不用生成一个新拷贝。
而throw obj
会拷贝构造一个新异常,且拷贝构造时使用静态类型,通常会改变异常的类型(从继承类变为基类)。
# 要通过引用捕获异常
用过引用捕获异常,可以避免以下问题
- 不会为是否删除异常对象而烦恼(传指针)
- 能够避开 slicing 异常对象(传值)
- 能够捕获标准异常类型(传指针)
- 减少异常对象被拷贝的次数(传值,两次)
所以,尽量要通过引用捕获异常!