1-9 在编程中使用异常

1.9 在编程中使用异常

1.9.1 什么时候避免异常

1. 不要在异步事件中使用异常

由于异步事件与源程序不在同一函数调用栈上,因此在异步中的异常不能正常抛给源程序。

2. 不要在处理简单错误时使用异常

如果在当前能得到足够的信息来处理错误,就不要把异常抛回给更大的语境中。

下面是一段与ai的对话,来说明这个建议:

[不要在处理简单错误时使用异常](./otherSource/ChatGPT API Demo.html)

3. 不要将异常用于程序的流程控制

由于异常处理付出的代价会大很多,因此不要将异常用于处理错误之外的地方。

4. 不要强迫自己使用异常

对于一些小型实用程序,不必费劲捕获可能的所有的异常。

1.9.2 异常的典型应用

1. 什么时候使用异常规格说明
  • 任何时候如果要使用异常规格说明,或调用使用异常规格说明的函数,最好编写自己的unexpected()函数,在这个unexpected()函数中将消息记入日志,然后抛出异常或终止程序。

  • 如前所述,应该避免在模板类中使用异常规格说明,因为无法预料模板参数类(template parameter classes)所抛出的异常的类型。

2. 从标准异常开始
  • 检查自己的系统异常是否符合标准库中异常类的定义,使用标准异常能使用户更容易理解和处理。

  • 即使标准异常不符合要求,也先考虑从其中继承,使用what()接口来对用户显示友好。

3. 嵌套用户自己的异常
  • 如果需要创建异常类,最好避免这个异常类污染命名空间。

4. 使用异常层次结构
  • 为用户提供一个有价值的分类方法

  • 通过最后的基类异常捕获,防止新的派生异常被忽略,同时可以减少代码修改量

5. 通过引用而不是值来捕获异常
  • 异常对象被传递到异常处理器时,避免进行不必要的对象拷贝

  • 派生对象被当成基类对象捕获时,避免发生对象切割

详细见下方链接:

使用引用捕获异常

6. 在构造函数中抛出异常
  • 由于构造函数没有返回值,因此使用异常代替于其它检测方式更加安全有效。

  • 在构造函数中抛出异常时,注意对象内部的指针和它的清理方式。

经典步骤见下方链接:

在构造函数抛出异常的正确做法

7. 不要在析构函数中触发异常
  • 绝不要在析构函数中抛出异常,否则可能导致terminate()函数的发生

  • 如果析构函数调用的函数可能抛出异常,那么在析构函数中使用try块来保证异常不会泄露出去。