何时以及如何使用exception处理?

我正在阅读有关exception处理。 我得到了一些关于什么exception处理的信息,但是我有几个问题:

  1. 何时抛出exception?
  2. 而不是抛出一个exception,我们可以使用返回值来指示错误?
  3. 如果我通过try-catch块来保护我所有的函数,是不是会降低性能?
  4. 何时使用exception处理?
  5. 我看到一个项目,该项目中的每个函数都包含一个try-catch块(即整个函数中的代码被try-catch块包围)。 这是一个很好的做法吗?
  6. try-catch和__try __except有什么区别?

这是一个非常全面的例外指南,我认为这是一个必读:

exception和error handling – C ++ FAQ或C ++ FAQ lite

作为一般的经验法则,当你的程序可以识别一个阻止执行的外部问题时抛出exception。 如果您从服务器接收到数据并且该数据无效,请抛出exception。 磁盘空间不足? 抛出exception。 宇宙射线阻止你查询数据库? 抛出exception。 但是,如果你从自己的程序中得到一些无效的数据 – 不要抛出exception。 如果您的问题来自您自己的错误代码,最好使用ASSERT来防范它。 需要exception处理来识别程序无法处理的问题,并告诉用户有关用户,因为用户可以处理它们。 但是,程序中的错误并不是用户可以处理的,所以程序崩溃将告诉我们,“值的answer_to_life_and_universe_and_everything不是42!这不应该发生!!!! 11”例外。

抓住一个例外,你可以做一些有用的事情,如显示一个消息框。 我更喜欢在一个处理用户input的函数中捕获一个exception。 例如,用户按下button“歼灭所有的hunams”,并在annihilateAllHunamsClicked()函数里面有一个try … catch块来说“我不行”。 即使歼灭hunamkind是一个复杂的操作,需要调用几十个和几十个函数,但只有一个try … catch,因为对于用户来说,它是一个primefaces操作 – 单击一个button。 在每个function中的exception检查是多余的和丑陋的。

此外,我不build议足够熟悉RAII – 也就是说,确保所有初始化的数据自动销毁。 这可以通过在堆栈上尽可能地初始化来实现,而当你需要在堆上初始化时,使用某种智能指针。 在堆栈上初始化的东西在抛出exception时会自动销毁。 如果你使用C风格的哑指针,当抛出exception的时候会冒内存泄漏的风险,因为在exception时没有人清理它们(当然,你可以使用C风格的指针作为类的成员,但要确保它们是在破坏者照顾)。

例外情况在各种情况下都很有用。

首先,前置条件计算的成本有一些高的function,如果发现前置条件不符合,只需要进行计算和exception终止。 例如,你不能倒置一个奇异matrix,但是要计算它是否是奇异的,你要计算一个非常昂贵的行列式:它可能必须在函数内完成,所以只需要“尝试”反转matrix并报告如果你不能抛出一个exception,就会报错。 这基本上是一个例外,作为负面的先决条件的使用。

那么还有其他的情况,你的代码已经很复杂了,并且在调用链上传递错误信息是困难的。 这部分是因为C和C ++破坏了数据结构模型:还有其他更好的方法,但是C ++不支持它们(比如在Haskell中使用monad)。 这个用法基本上是我不能这样做,所以我会抛出一个例外 :它不是正确的方式,但它是实用的。

那么主要是使用exception情况:报告外部前提条件或不variables(如内存或磁盘空间等足够资源)何时不可用。 在这种情况下,您通常会终止该程序或其中的一个主要部分,而例外情况是传输有关该问题的信息的好方法。 C ++ Exceptions被devise用于报告阻止程序继续的错误

包括C ++在内的大多数现代语言中使用的exception处理模型已知被打破。 这是非常强大的。 现在理论家们已经开发出了比完全公开的“抛东西”和“也许也许不抓它”模型更好的模型。 另外使用types信息来分类exception并不是一个好主意。

所以,最好的办法就是谨慎地抛出exception,当出现实际错误时,以及没有其他方式来处理它,尽可能接近抛出点来捕捉exception

最好阅读这个

在过去的十五年中,exception处理已经被讨论了很多。 然而,尽pipe就如何妥善处理例外达成了普遍共识,但使用上的分歧仍然存在。 错误的exception处理很容易发现,容易避免,而且是一个简单的代码(和开发者)质量指标。 我知道绝对的规则是非常谨慎或夸大的,但作为一般规则,你不应该使用try / catch

http://codebetter.com/karlseguin/2010/01/25/don-t-use-try-catch/

如果您的问题来自您自己的错误代码,最好使用ASSERT来防范它。 需要exception处理来识别程序无法处理的问题,并告诉用户有关用户,因为用户可以处理它们。 但是程序中的错误并不是用户可以处理的,所以程序崩溃会告诉我们很多

我不同意接受答案的这一方面。 断言并不比抛出exception更好。 如果exception仅适用于运行时错误(或“外部问题”), std::logic_error是什么?

一个逻辑错误几乎是由于定义阻止程序继续的条件。 如果程序是一个逻辑结构,并且一个条件发生在该逻辑的范围之外,它将如何继续? 收集你们可能的投入,抛出一个exception!

这不是没有现有的艺术。 std::vector仅仅是一个名字,会抛出一个逻辑错误exception,即std::out_of_range 。 如果您使用标准库,并且没有顶级处理程序来捕获标准exception – 如果只调用what ()并退出 (3) – 那么您的程序将受到突然静默,终止。

断言macros是一个非常弱的后卫。 没有恢复。 除非你没有运行一个debugging版本,在这种情况下没有执行 。 断言macros属于当今计算速度比现在慢6个数量级的时代。 如果你要麻烦testing逻辑错误,而不是在testing时使用testing,那么在生产中,最好对代码有很大的信心!

标准库提供逻辑错误exception,并使用它们。 他们在那里有一个原因:因为逻辑错误发生,并且是例外。 仅仅因为C特性的断言是没有理由依赖这样一个原始的(而且可以说是无用的)机制,当一个exception处理这个工作好得多。

1.代码中包含一个exception检查,当有可能在这个问题之间得到一个exception。

2.只有在需要的情况下才使用try-catch块。 每个try-catch块的使用增加了一个额外的条件检查,肯定会减less代码的优化。

我认为_try_except是一个有效的variables名称….

基本的区别是:

  1. 一个为你做error handling。
  2. 一个是你自己做的。

    • 例如,你有一个expression式可以使0 divide error 。 使用try catch 1.会在发生错误时帮助你。 或者你需要if a==0 then..2.

    • 如果你不尝试捕捉exception,我不认为它更快,它只是简单的绕过,如果发生error ,它将被threw外部处理程序。

交给你自己就意味着问题不再进一步在许多情况下在速度上有优势,但并不总是如此。

build议:只要简单和合乎逻辑的情况下处理自己。

许多C / C ++纯粹主义者完全拒绝exception。 主要的批评是:

  1. 这很慢 – 当然不是真的“慢”。 但是,与纯粹的c / c ++相比,存在相当多的开销。
  2. 它引入了错误 – 如果你没有正确处理exception,你可能会错过抛出exception的函数中的清理代码。

而是每次调用函数时检查返回值/错误代码。