5

我目前正在使用 Visual Studio Express C++ 2008,并且对 catch 块排序有一些疑问。不幸的是,我在互联网上找不到答案,所以我向专家提出这些问题。

我注意到除非将 catch (...) 放在 catch 块的末尾,否则编译将失败并出现错误 C2311。例如,以下将编译:

catch (MyException)
{
}
catch (...)
{
}

而以下不会:

catch (...)
{
}
catch (MyException)
{
}

一个。请问这是在 C++ 语言标准中定义的,还是只是 Microsoft 编译器严格?

湾。C# 和 Java 也有相同的规则吗?

C。顺便说一句,我也尝试过创建一个基类和一个派生类,并将基类的 catch 语句放在派生类的 catch 语句之前。这编译没有问题。请问有没有防止这种做法的语言标准?

4

3 回答 3

5

根据标准,订单很重要。基本上,与异常匹配的第一个捕获将被捕获。

a) 因为catch(...)会使任何后续捕获无关紧要,标准只允许它是最后一个捕获。

b) C# 和 Java 有类似的规则。

c) 在派生类之前捕获(通过引用或指针)基类将使派生类的代码无关紧要。但是,该标准确实允许这样做

于 2010-03-08T22:04:42.003 回答
3

来自 C++ 标准 15.3/5“处理异常”:

try 块的处理程序按出现的顺序进行尝试。这使得编写永远无法执行的处理程序成为可能,例如通过将派生类的处理程序放置在相应基类的处理程序之后。

A...在处理程序的异常声明函数中类似于...在函数参数声明中;它为任何异常指定匹配项。如果存在,...则处理程序应为其 try 块的最后处理程序。

于 2010-03-08T22:04:39.540 回答
3

所谓的默认处理程序catch(...)必须是处理程序列表中的最后一个处理程序。这确实是标准要求的。但是,此要求特定于默认处理程序。

否则,标准不会限制处理程序的顺序,这意味着通常您可以创建一个处理程序来“拦截”所有异常,否则这些异常会到达列表中的其他处理程序(从而使后一个处理程序无用)。

catch此外,多次重复相同的子句(具有相同的类型)是完全合法的

catch (int) {
  // ...
}
catch (int) {
  // ...
}

即使只有第一个有机会抓住任何东西。一个好的编译器会针对这种情况发出警告,但从形式上讲,这不是错误。

于 2010-03-08T22:06:35.380 回答