3.5.3 错误处理替代
错误处理在现实世界的所有软件中都是一个主要问题,因此很自然地有很多解决方法。如果错误被检测出来后无法在函数内局部处理,函数就必须以某种方法与某个调用者沟通这个问题。抛出异常是C++解决此问题的最一般的方法。
在有的语言中,提供异常机制的目的是为返回值提供一种替代机制。但C++不是这样的语言:异常是用来报告错误、完成给定任务的。异常与构造函数和析构函数一起为错误处理和资源管理提供一个一致的框架(参见4.2.2节、5.3节)。当前的编译器都针对返回值进行了优化,使其比抛出一个相同的值作为异常高效得多。
对于错误不能局部处理的问题,抛出异常不是报告错误的唯一方法。函数可用如下方式指出它无法完成分配给它的任务:
·抛出一个异常。
·以某种方式返回一个值来指出错误。
·终止程序(通过调用terminate()、exit()或abort()这样的函数)。
在下列情况下,我们返回一个错误指示符(一个“错误码”):
·错误是常规的、预期的。例如,打开文件的请求失败就是很正常的(可能没有给定名字的文件或文件不能按请求的权限打开)。
·预计直接调用者能合理地处理错误。
在下列情况下我们抛出异常:
·错误很罕见,以致程序员很可能忘记检查它。例如,你最后一次检查printf()的返回值是什么时候?
·立即调用者无法处理错误。取而代之,错误必须层层回到最终调用者。例如,让一个应用中的所有函数都可靠地处理每个分配错误或网络故障是不可行的。
·在一个应用中,底层模块添加了新的错误类型,以致编写高层模块时不可能处理这种错误。例如,当修改一个旧的单线程应用令其能使用多线程,或使用放置在远端需要通过网络访问的资源时。
·错误代码没有合适的返回路径。例如,构造函数无法返回值给“调用者”检查。特别是,构造函数的调用是发生在构造多个局部变量时或是在一个复杂对象构造了一部分时,这样基于错误码的清理工作就会变得非常复杂。 ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access