如何处理未经检查的异常?

5
Java有编译器检查异常。当我转向C++时,我发现它没有检查异常。起初,我继续使用异常处理,因为这是一个很好的特性。然而,过了一段时间后,我放弃了它,因为我进入了每个函数都可能抛出异常的情况。由于我写的函数中只有很小一部分可以抛出异常(最多只有25%),我发现对于那些不可能抛出任何东西的函数来说,做异常处理的开销是不可接受的。
因此,我真的很惊讶有很多开发人员喜欢未经检查的异常。因此,我很想知道他们如何解决这个问题。在语言不支持检查异常的情况下,你如何避免做不必要的异常处理开销备注:我的问题同样适用于C++和C#,以及可能所有其他不具备编译器检查异常处理的语言。

并非每个函数都可能抛出异常。声明为“noexcept”的函数不能抛出异常(如果尝试这样做,将调用std::terminate())。 - Shirik
4个回答

16
简单来说,在C++中你不需要在“每个可能会抛出异常的函数”中进行异常处理,因为几乎每个函数都有这个可能性。相反,你应该在应用程序中的某些关键点上进行处理,在那里可以产生明智的、特定于应用程序的诊断,并采取明智的、特定于应用程序的纠正措施,尽管使用RAII惯用语法意味着(如avakar在他的答案中指出的那样)通常情况下不需要采取太多的纠正措施。

没错,这就是它们的作用。谁(哪段代码)知道如何处理,就由谁来处理。 - sharptooth
Double exactly: 也可参见https://dev59.com/oEbRa4cB1Zd3GeqPyDWy#434903。 - peSHIr
3
同意。RAII 可以自动完成 Java 开发人员手动处理的 99% 工作,只需在剩余的 1% 案例中添加异常处理即可。同时请注意,80% 的统计数据都是虚构的,但你懂我的意思。 - Martin York

11

当我开始学习使用C#时,我也感到害怕。但后来发现,这并不经常发生。我很少能够捕获异常并且对其进行有用的处理... 几乎所有的异常都会冒泡到栈顶附近的某个位置,然后通过中止请求或其他方式来处理。

现在当我写Java代码时,我发现受检异常常常让人非常沮丧。我认为这里面确实存在一些价值,但它引入了和解决的问题同样多。

基本上,我认为我们还没有真正做好错误处理方面的事情,但总体而言,我更喜欢C#的方法而不是Java的方法。


1
同意。这是开发中我认为仍需要一些研究的领域。 - Martin York

4
除了Neil所说的,您还应该注意到,没有必要使用try/finally(或在C++上下文中使用try/catch/throw),因为即使抛出异常,也会调用对象析构函数
非常容易编写具有异常安全性的代码,只需很少使用try语句即可。

当尼尔提到RAII时,他说的就是这个。 - Martin York
1
他还提到了我的回答,表明在我发布回答之后,他对自己的回答进行了编辑。 - avakar

3
专门针对C++,如果你设计好你的类并使用RAII,开销基本上就消失了。
Martin York在这个答案中写了一个很好的例子。
该函数仍然可以抛出异常,但如果它抛出异常,它不需要做任何特殊的清理工作。所以你只需要在一个地方捕获异常——能够处理并从错误中恢复的函数中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接