一个 "throw;" 语句是什么意思?

56

最近我一直在阅读C++ F.A.Q,尤其是这个页面

通过这部分内容的阅读,我发现了一种被作者称为“异常调度程序”的技术,它允许某人将所有的异常处理集中在一个方便的函数中:

void handleException()
{
  try {
    throw; // ?!
  }
  catch (MyException& e) {
    //...code to handle MyException...
  }
  catch (YourException& e) {
    //...code to handle YourException...
  }
}

void f()
{
  try {
    //...something that might throw...
  }
  catch (...) {
    handleException();
  }
}

令我困扰的是单个throw;语句:如果考虑给定的示例,那么肯定很明显它的作用:它首先重新抛出在f()中捕获的异常并再次处理。

但是,如果我直接调用handleException()而不是从catch()子句中执行该操作,是否有任何指定的行为?

此外,额外加分的是,你是否知道throw的任何其他“奇怪”(可能不是恰当的词)用法?

谢谢。


你在你的链接页面上读到这个了吗?http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.15 在这个例子中,语句throw;的意思是“重新抛出当前异常”。 - Fred Larson
@Fred Larson:当然。但是如果没有“当前”异常的情况下会发生什么? - ereOn
我找到了答案,但是@dalle比我更快。 - Fred Larson
3个回答

55
如果你只使用 `throw;`,并且没有当前的异常可以重新抛出,那么程序将会突然终止。(更准确地说,将会调用 `terminate()`。)
请注意,`throw;` 是重新抛出当前异常的唯一安全方式 - 它不等同于:
```catch (exception const & e) { throw e; }```

谢谢你的回答。这可能是另一个问题的一部分,但肯定相关:你能解释一下在你最后一句中调用 "throw;" 和 "throw e;" 的区别吗?我不知道它们之间的区别。 - ereOn
2
@ereOn:我认为至少有一个区别是,throw;将保留原始异常类型,而throw e;可能会切片。 - Fred Larson
@Fred Larson:我认为切片可能只会在按值捕获时发生。但你可能是对的(我完全不确定)。有人可以确认吗? - ereOn
12
是的 - throw e; 抛出一个与 e 的静态类型相同的新异常,而不是动态类型 - 因此如果 e 是多态的,它可以进行切片。 - Alan Stokes
此外,第二个示例只有在当前异常派生自 std::exception 时才会重新抛出异常,对吗? - NHDaly
1
@NHDaly 是的。任何其他异常都不会被捕获(因此也不需要重新抛出)。但是好心的人不会抛出不派生自std::exception的东西。 - Alan Stokes

41

是的,它指定了行为,它将调用terminate;

15.1第8段:如果目前没有正在处理的异常,并执行没有操作数的throw表达式,则调用terminate()(15.5.1)。


3
我希望我也能接受这个答案:我选择了Alan Stokes的回答,因为他目前的声望比你低。他也提供了详细准确的回答。不过我还是点赞了这个答案以表示公正。非常感谢。 - ereOn

8

这就是所谓的异常处理程序。如果有任何"当前异常",它将重新抛出该异常。如果当前没有正在处理的异常,则会调用terminate()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接