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

C++ 何时以及如何使用异常处理?,c++,windows,exception,exception-handling,C++,Windows,Exception,Exception Handling,我正在阅读有关异常处理的文章。我得到了一些关于异常处理是什么的信息,但我有几个问题: 何时抛出异常 我们可以使用返回值来指示错误,而不是抛出异常吗 如果我通过try-catch块来保护我的所有函数,它不会降低性能吗 何时使用异常处理 我看到一个项目,其中该项目中的每个函数都包含一个try-catch块(即整个函数中的代码被try-catch块包围)。这是一种好的做法吗 试抓和试除有什么区别 1.当可能导致异常或问题之间的某个地方出现异常时,代码中会包含异常检查 2.仅在需要的情况下使用try c

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

  • 何时抛出异常
  • 我们可以使用返回值来指示错误,而不是抛出异常吗
  • 如果我通过try-catch块来保护我的所有函数,它不会降低性能吗
  • 何时使用异常处理
  • 我看到一个项目,其中该项目中的每个函数都包含一个try-catch块(即整个函数中的代码被try-catch块包围)。这是一种好的做法吗
  • 试抓和试除有什么区别

  • 1.当可能导致异常或问题之间的某个地方出现异常时,代码中会包含异常检查

    2.仅在需要的情况下使用try catch block。每个try-catch块的使用都会增加额外的条件检查,这无疑会减少代码的优化


    3.我认为_try_except是一个有效的变量名……

    许多C/C++纯粹主义者完全不鼓励异常。主要批评有:

  • 它很慢——当然它不是真的“慢”。然而,与纯c/c++相比,有相当大的开销
  • 它引入了bug——如果你不能正确处理异常,你可能会错过抛出异常的函数中的清理代码
    相反,每次调用函数时都要检查返回值/错误代码。

    基本区别是:

  • 一个为你做错误处理
  • 一个是你自己做

    • 例如,您有一个表达式可以使
      0除错误
      。使用try-catch
      1。
      将在发生错误时帮助您。或者,如果a==0,则在
      2中需要一个

    • 如果您不尝试捕获异常,我认为它不会更快,它只是简单地绕过,如果发生
      错误
      ,它将被
      抛出
      到外部处理程序

  • 在很多情况下,把自己交给别人意味着问题不会再进一步,在速度上会有优势,但并非总是如此


    建议:在简单且合乎逻辑的情况下处理自己。

    以下是关于例外情况的全面指南,我认为这是一本必读的书:

    异常和错误处理-或

    一般来说,当程序能够识别阻止执行的外部问题时,抛出异常。如果从服务器接收到数据且该数据无效,则引发异常。磁盘空间不足?抛出异常。宇宙射线阻止你查询数据库?抛出异常。但是,如果您从自己的程序内部获得一些无效数据,请不要抛出异常。如果您的问题来自您自己的错误代码,那么最好使用断言来防范它。异常处理需要识别程序无法处理的问题,并告诉他们关于用户的情况,因为用户可以处理这些问题。但是程序中的错误不是用户可以处理的,所以程序崩溃会告诉你的不少于“答案对生命和宇宙的价值”和“一切都不是42!这永远不会发生!!!!11”例外

    捕获一个异常,您可以在其中执行一些有用的操作,例如显示消息框。我更喜欢在以某种方式处理用户输入的函数中捕获一次异常。例如,用户按下按钮“歼灭所有匈牙利人”,在函数的内部有一个try…catch块来表示“我不能”。尽管消灭hunamkind是一个复杂的操作,需要调用几十个函数,但只有一个try…catch,因为对于用户来说,这是一个原子操作——点击一个按钮。每个函数中的异常检查都是冗余的和丑陋的


    此外,我不建议对RAII有足够的了解——也就是说,确保所有初始化的数据都被自动销毁。这可以通过在堆栈上尽可能多地初始化来实现,当需要在堆上初始化某些内容时,使用某种智能指针。当抛出异常时,堆栈上初始化的所有内容都将自动销毁。如果您使用C样式的哑指针,则在引发异常时会有内存泄漏的风险,因为没有人在发生异常时清理它们(当然,您可以将C样式指针用作类的成员,但请确保它们在析构函数中得到处理)。

    异常在各种情况下都很有用

    首先,有些函数计算前置条件的成本非常高,如果发现不满足前置条件,最好只进行计算并异常中止。例如,您无法反转奇异矩阵,但是要计算它是否奇异,您需要计算非常昂贵的行列式:无论如何,它可能必须在函数内部完成,因此只需“尝试”反转矩阵,如果不能,则通过抛出异常报告错误。这基本上是一个例外,作为否定的先决条件使用

    还有一些情况下,代码已经很复杂,很难在调用链上传递错误信息。这部分是因为C和C++已经破坏了数据结构模型:还有其他更好的方法,但是C++不支持它们(比如在Haskell中使用单子)。这种用法基本上是我懒得把它做对,所以我会抛出一个异常:这不是正确的方法,但很实用

    然后是异常的主要用途:报告外部先决条件或不变量(如内存或磁盘空间等足够的资源)何时不可用。在这种情况下,您通常会终止程序或其主要部分,而异常是传输有关问题信息的一种好方法C++Ex