6

我将 QT 4.8 (C++) 用于桌面应用程序项目,并编写如下异常处理:

void callerMethod()
{
  try
  {
   method1();
  }
  catch(Exception1& e)
  {
    // display critcal error message
    // abort application
  }
  catch(std::Exception& e)
  {
   // print exception error message
  }
  catch(...)
  {
   // print unknown exception message
  } 
}

void method1()
{
  try
  {
   // some initializations
   // some operations (here exceptions can occur)
   // clean-up code (for successful operation i.e no exception occurred)
  }
  catch(Exception1& e)
  {
   // clean-up code
   throw e;
  }
  catch(Exception2& e)
  {
   // clean-up code
   throw e;
  }
  catch(Exception3& e)
  {
   // clean-up code
   throw e;
  }
  catch(...)
  {
   // clean-up code
   throw;
  }
}

所以我的问题是我需要在每个 catch 块中编写清理代码吗?有什么办法可以避免编写重复的代码

注意:: [ In method1() ] 我想重新抛出发生在我的调用者身上的异常。所以我不能在单个 catch 块中捕获它们,因为这样会丢失类型信息。

4

3 回答 3

8

Method1可以通过两个概念大大简化:

  1. 雷伊。将任何清理代码放入析构函数中,清理代码将被集中。
  2. 使用 unqualified throw,您将不需要知道抛出的异常类型。

所以,method1()应该是这样的:

void method1()
{
     // some initializations of RAII objects
     // some operations (here exceptions can occur)
}

如果从 Exception1 派生,则可以删除第一个catch子句,因为该方法是虚拟的。callerMethodstd::exceptionwhat()

于 2012-04-21T06:44:43.797 回答
1

您应该尽可能低地抛出异常,并在调用链中尽可能高地捕获它们。这会自动减少代码重复,并集中错误处理。你在一个地方投掷/接球,这似乎有点……强迫。

我经常做这种事情(特别是对于程序结束异常:

int main()
try
{
    function_calls_that_may_throw();
    // ...
}
catch(my_exception& e)
{
    e.do_exception_stuff();
}
catch(std::exception& e)
{
    std::cout << e.what();
}
catch(...)
{
    std::cout << "Something bad happened.\n";
}

这仅适用于抛出您不打算更好地处理或重试失败的操作等的异常。

这种方法的优点是所有/大多数错误处理代码都在程序的顶层,调用链中的所有函数都不必担心这些东西,它们所做的只是抛出一个异常当他们喜欢的时候。

于 2012-04-21T07:25:55.540 回答
0

如果所有清理代码完全相同,则可以在 catch (...) 块中执行所有操作:

try {
   // code
} catch (...) {
   // cleanup
   throw;
}

如果您的代码略有不同,您可以随时调用清理函数:

try {
   // code
} catch (exc1 ex) {
   cleanup(args);
   // exc1 specific
   throw;
} catch (exc2 ex) {
   cleanup(args);
   // exc2 specific
   throw;
} catch (...) {
   cleanup(args);
   throw;
}
于 2012-04-21T06:44:51.073 回答