经过一番阅读,我意识到,在 C++ 中,异常规范被认为是一件坏事:
int f() throw(A, B); // bad because a lot of reasons
我不明白的是如何替换它。我如何告诉f()
's 调用者他必须捕获异常?
怎么样
//throws: A if something is wrong
// B if something else is wrong
int f();
你没有。什么都不说意味着它可以扔任何东西。
我假设你有一些 Java 背景来问这个问题。编译时异常检查是一个失败的 Java 实验。这就是为什么你在其他任何地方都看不到它。
异常处理的一般规则是:尽可能处理。这通常归结为一个try-catch
非常高的层次,你基本上告诉用户他试图做的任何事情都失败了。能够从异常中恢复并继续操作是非常罕见的。
当然,您应该提供文档说明您的函数会抛出哪些异常。我不认为这可以替代 throw 规范(其目的非常不同)。您应该记录您的函数抛出的异常,并且可以由调用者有意义地处理,而抛出规范必须列出该函数(及其调用的函数)可能出现的任何异常。
您可以将其替换为自动文档工具。
此类工具通常能够很好地格式化方法将抛出的异常,例如 doxygen \exception 命令(或 \throw 或 \throws)。假设您的代码的用户阅读了文档,他们将能够找出要捕获的异常。
/**
* @exception A
* @exception B
*/
int f();
有关更多有用信息,请参阅此问题:如何记录函数可能抛出的所有异常?
我如何告诉 f() 的调用者他必须捕获异常?
您认为调用者必须捕获异常表明您的设计可能有问题。您是否使用异常来表示非异常情况,例如文件结束?
强制直接调用者捕获所有可能的异常是糟糕的设计。示例:push_back
标准库容器的成员函数分配内存,这可能会失败。库的设计者并不期望调用者将每一个都包装push_back
在一个try/catch
块中。这没有意义。这样做会使代码更难看,更难测试。此外,您将如何从内存不足的情况中恢复?处理一次,在高层次上,几乎是你所能做的。