5

如果我有如下代码:

try {
  doSomething();
} catch (...) {
  noteError();
}

void noteError() {
  try {
    throw;
  } catch (std::exception &err) {
    std::cerr << "Note known error here: " << err.what();
  } catch (...) {
    std::cerr << "Note unknown error here.";
  }
  throw;
}

原始异常会从 noteError() 的下框架内的两个地方抛出吗?

4

2 回答 2

6

您的原始代码很好。您捕获了不同的异常类型并调用了一个记录消息并重新抛出的函数。该throw语句不需要直接出现在相应的catch块内。但是,如果您调用其中一个“注释”函数并且您当前没有处理异常,那么您的程序将调用terminate().

你的新代码也很好。可以捕获所有内容,然后调用另一个重新抛出的函数以转到更具体的处理程序。这就是C++ FAQ 中描述异常调度程序惯用语。在调度块完成后重新抛出异常看起来有点奇怪,但是如果在返回后(在原始块内)throw发生了相同的语句而不是现在的位置,那么它将是完全普通的;它在标准§15.1/6 中得到了证明。noteErrorcatch

于 2010-08-24T22:42:57.163 回答
4

标准(§15.1/2)中的措辞是(强调我的):

当抛出异常时,控制权转移到最近的具有匹配类型的处理程序(15.3);“最近的”表示 try 关键字后面的复合语句、ctor-initializer 或函数体最近由控制线程进入但尚未退出的处理程序。

try 块何时“退出”?根据语法(§15/1),try 块以一系列处理程序结束,因此块在最后一个处理程序结束时结束。换句话说:

try // <- start of try block
{
}
catch (whatever) // <- first handler
{
}
// ... more handlers
catch (whatever_again) // <- last handler
{
} // <- end of try block

所以是的,你的代码很好。重新抛出时,最近的 try 块有一个匹配的处理程序(即catch (...)),因此进入该处理程序。

于 2010-08-24T23:17:14.657 回答