【问题标题】:Two methods to catch exception, which one is preferable?两种捕获异常的方法,哪一种更可取?
【发布时间】:2013-07-16 00:59:54
【问题描述】:

好的,有一个叫做 doProcess() 的函数,我想捕获这个函数内部可能发生的异常。我很困惑,因为有时我注意到如果我们尝试在函数内部或外部捕获异常会有一些不同。 所以请告诉我有什么区别,哪种方法更可取? 我在 Win 7 中使用 VS C++ 2010。谢谢。

捕捉函数内部..

void doProcess()
{
  try{
      for(int i=0; i<n; i++)
      {
         Performcalculations();
         .
         .
         .
      }
      performanotherProcess();
      .
      .
  }
  catch(exception e) {
      cout<<e.what()<<endl;
  }

}

在回调函数中捕捉外部。

void callback()
{
   try{
      doProcess();
   }
   catch(exception e) {
      cout<<e.what()<<endl;
   }
}

【问题讨论】:

  • &lt;&lt;cout 这是什么?
  • 如果您可以处理doProcess 中的异常,请执行此操作。
  • @Ryan Haining,这是人为错误。 ;) 我的错。已更正。
  • 第二个代码块中还有一个
  • “我注意到有一些不同” - 有什么不同?

标签: c++ visual-c++ exception exception-handling


【解决方案1】:

这取决于哪个级别可以最好地处理异常。根据具体情况,您甚至可能希望在较低级别捕获它,执行一些异常处理操作,然后重新抛出它并在较高级别再次捕获它以进一步处理它。

异常处理可能涉及在没有抛出异常的情况下不执行的特殊操作。示例包括:

  • 记录警告或错误消息
  • 清理资源
  • 修改参数并重新尝试运行失败的函数
  • 在重新抛出异常对象之前添加信息

对于低级函数,并非所有这些操作都是可能的。例如,记录器可能在低级别不可用,或者某些需要清理的资源可能无法从那里访问。在这些情况下,您需要抛出(或捕获并重新抛出)异常并在更高级别上捕获它。

这完全取决于哪个级别可以访问处理异常所需的资源。多次捕获和重新抛出,或者作为不同的异常类型捕获和重新抛出,也是完全可能的,有时是正确的做法。


我还应该说,通过引用而不是复制来捕获异常通常是个好主意:

catch (my_exception &e)
{ /*...*/ }

原因包括:a) 您保存了一份副本,b) 您受益于类型多态性(因为异常通常是异常类型的类型层次结构的一部分),c) 您可以以自然的方式调用原始异常对象和/或在它被捕获和重新抛出的每个级别上添加信息。如果您不添加信息,而只是捕获(并可能重新抛出),也可以将其捕获为const-reference。

【讨论】:

  • 您通常通过 const 引用 而不是纯引用来传递它。
  • @Rapptz 对此意见不一,还有其他问题在 cmets 中进行了讨论。我不会争论哪个更好。在任何情况下,两者都不是不正确的或极具风险的。
【解决方案2】:

在你处理的地方捕获期望,如果你想让doProcess()有期望句柄,那么你应该把try{}catch(){}放在doProcess()中,但是如果你想要doProcess()可以报告一个期望,然后只做投掷工作。这取决于您的代码和您的设计。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-19
    • 2016-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多