何时以及如何使用异常处理?

我正在读关于异常处理。我得到了一些关于异常处理的信息,但我有几个问题: 什么时候抛出异常? 我们可以使用返回值来指示错误,而不是抛出异常吗? 如果我通过try-catch块保护我的所有功能,它不会降低性能吗? 何时使用异常处理? 我看到一个项目,该项目中的每个函数都包含一个try-catch块(即整个函数内的代码被try-catch块包围)。这是一个好习惯吗? try-catch和__try __except有什么区别?     
已邀请:
这里有关于异常的全面指南,我认为是必读的: 异常和错误处理 - C ++ FAQ或C ++ FAQ lite 作为一般经验法则,当程序可以识别阻止执行的外部问题时抛出异常。如果从服务器接收数据并且该数据无效,则抛出异常。磁盘空间不足?抛出一个例外。宇宙射线阻止你查询数据库?抛出一个例外。但是如果你从你自己的程序中得到一些无效数据 - 不要抛出异常。如果您的问题来自您自己的错误代码,最好使用ASSERT来防范它。需要进行异常处理以识别程序无法处理的问题并告诉用户有关用户的问题,因为用户可以处理它们。但是你的程序中的错误并不是用户可以处理的东西,因此程序崩溃将比“answer_to_life_and_universe_and_everything的值不是42!这应该永远不会发生!!!! 11”异常少得多。 抓住一个例外,你可以用它做一些有用的事情,比如显示一个消息框。我喜欢在一个以某种方式处理用户输入的函数内部捕获异常。例如,用户按下按钮“Annihilate all hunams”,并且在annihilateAllHunamsClicked()函数内部有一个try ... catch块说“我不能”。即使摧毁hunamkind是一项复杂的操作,需要调用几十个和几十个函数,但只有一个尝试... catch,因为对于用户来说这是一个原子操作 - 一键式点击。每个函数中的异常检查都是冗余和丑陋的。 另外,我不能建议熟悉RAII - 也就是说,确保所有初始化的数据都被自动销毁。这可以通过在堆栈上尽可能多地初始化来实现,并且当您需要在堆上初始化某些东西时,使用某种智能指针。当抛出异常时,堆栈上初始化的所有内容都将被自动销毁。如果你使用C风格的哑指针,当抛出异常时你会冒内存泄漏的风险,因为没有人在异常时清理它们(当然,你可以使用C风格的指针作为你的类的成员,但要确保它们是在析构函数中处理)。     
例外在各种情况下都很有用。 首先,有一些函数,其中计算前置条件的成本如此之高,如果发现不满足前置条件,则最好只进行计算并中止异常。例如,你不能反转一个奇异矩阵,但要计算它是否是单数你计算非常昂贵的行列式:它可能必须在函数内完成,所以只需“试一试”反转矩阵并报告如果你不能通过抛出异常就会出错。这基本上是作为负前置条件使用的例外。 然后还有其他情况,您的代码已经很复杂,并且很难在调用链中传递错误信息。这部分是因为C和C ++已经破坏了数据结构模型:还有其他更好的方法,但C ++不支持它们(例如在Haskell中使用monad)。这种用法基本上是我不能纠正这样做,所以我会抛出一个例外:它不是正确的方法,但它是实用的。 然后主要使用例外:报告外部前置条件或不变量(例如内存或磁盘空间等资源)不可用的时间。在这种情况下,您通常会终止程序或程序的主要部分,例外是传输有关问题的信息的好方法。 C ++异常是为报告错误而设计的,这些错误会阻止程序继续运行。 已知大多数现代语言(包括C ++)中使用的异常处理模型已被破坏。它太强大了。理论家现在已经开发出比完全开放的“扔任何东西”和“可能也许不会抓住它”模型更好的模型。此外,使用类型信息对异常进行分类并不是一个好主意。 因此,你可以做的最好的事情就是谨慎地抛出异常,当出现实际错误时,以及没有其他方法可以处理它并捕获尽可能接近抛出点的异常。     
最好的阅读 在过去的十五年中,对异常处理进行了大量讨论。然而,尽管对如何正确处理例外达成了普遍共识,但仍然存在使用鸿沟。不正确的异常处理易于发现,易于避免,并且是一种简单的代码(和开发人员)质量指标。我知道绝对规则会变得过于贴心或夸张,但作为一般规则,你不应该使用try / catch http://codebetter.com/karlseguin/2010/01/25/don-t-use-try-catch/     
  如果您的问题来自您自己的错误代码,最好使用ASSERT来防范它。需要进行异常处理以识别程序无法处理的问题并告诉用户有关用户的问题,因为用户可以处理它们。但是程序中的错误并不是用户可以处理的,因此程序崩溃不会太多 我不同意接受的答案的这一方面。断言并不比抛出异常更好。如果异常仅适用于运行时错误(或“外部问题”),那么
std::logic_error
是什么? 逻辑错误几乎是定义阻止程序继续的条件。如果程序是逻辑构造,并且条件发生在该逻辑的域之外,那么它如何继续?你可以收集你的投入,然后抛出异常! 它不像现有技术那样。
std::vector
,仅举一例,抛出一个逻辑错误异常,即
std::out_of_range
。如果您使用标准库并且没有顶级处理程序来捕获标准异常 - 如果只调用what()和exit(3) - 那么您的程序将受到突然的静默,终止。 断言宏是一个弱得多的守卫。没有恢复。除非,即你没有运行调试版本,在这种情况下没有执行。断言宏属于计算比今天慢6个数量级的时代。如果您在测试逻辑错误时遇到麻烦,但在生产时不使用该测试,那么在生产中,您最好对代码充满信心! 标准库提供逻辑错误异常,并使用它们。它们存在是有原因的:因为逻辑错误发生,并且是例外。仅仅因为C特征断言没有理由依赖这种原始(并且可以说是无用的)机制,当异常处理工作时要好得多。     
1.当有可能在结果之间或问题之间的某处产生异常时,代码中会包含异常检查。 2.仅使用需要的情况使用try-catch块。每个try-catch块的使用增加了额外的条件检查,这肯定会减少代码的优化。 我认为_try_except是一个有效的变量名....     
基本的区别是: 一个为你做错误处理。 一个是你做自己的。 例如,你有一个表达式可以使
0 divide error
。使用trycatch
1.
可以在发生错误时帮助您。或者你需要
if a==0 then..
in
2.
如果你不尝试捕捉异常我不认为它更快,它只是简单地绕过,如果
error
发生它将是outer8ѭ外部处理程序。 交出自己意味着问题不会更进一步,在许多情况下在速度方面具有优势,但并非总是如此。 建议:在简单和逻辑上处理你自己。     
许多C / C ++纯粹主义者完全不鼓励例外。主要批评是: 它很慢 - 当然它并不是真的“慢”。但是,与纯c / c ++相比,存在相当多的开销。 它引入了错误 - 如果你没有正确处理异常,你可能会错过抛出异常的函数中的清理代码。 而是每次调用函数时检查返回值/错误代码。     

要回复问题请先登录注册