我目前正在使用Visual Studio Express C ++ 2008,并且对catch块排序有一些疑问。不幸的是,我无法在互联网上找到答案,所以我向专家提出了这些问题。
我注意到除非catch(...)放在catch块的末尾,否则编译将失败,错误C2311。例如,以下内容将编译:
catch (MyException)
{
}
catch (...)
{
}
而以下情况不会:
catch (...)
{
}
catch (MyException)
{
}
一个。我是否可以问这是否是在C ++语言标准中定义的,或者这只是Microsoft编译器是严格的?
湾C#和Java是否也有相同的规则?
℃。另外,我还尝试创建基类和派生类,并在派生类的catch语句之前放置基类的catch语句。这编译没有问题。请不要有语言标准来防范这种做法吗?
答案 0 :(得分:5)
根据标准,订单很重要。基本上,将捕获匹配异常的第一个catch。
a)因为catch(...)
会使任何后续捕获无关紧要,标准只允许它成为最后一次捕获。
b)C#和Java有类似的规则。
c)在派生类使得派生的代码无关紧要之前捕获(通过引用或指针)。但是,该标准确实允许这个
答案 1 :(得分:3)
从C ++标准15.3 / 5“处理异常”:
尝试块的处理程序按外观顺序进行尝试。这使得编写永远不会执行的处理程序成为可能,例如通过在相应基类的处理程序之后放置派生类的处理程序。
处理程序的异常声明中的
...
与函数参数声明中的...
类似;它指定任何异常的匹配项。如果存在,...
处理程序应该是其try块的最后一个处理程序。
答案 2 :(得分:3)
所谓的默认处理程序catch(...)
必须是处理程序列表中的最后一个处理程序。这确实是标准所要求的。但是,此要求特定于默认处理程序。
否则标准不会限制处理程序的顺序,这意味着通常可以创建一个处理程序来“拦截”所有异常,否则这些异常会到达列表中的其他处理程序(从而使后一个处理程序无用)。 / p>
此外,多次重复相同的catch
子句(具有相同类型)是完全合法的
catch (int) {
// ...
}
catch (int) {
// ...
}
尽管只有第一个人有机会抓到任何东西。一个好的编译器会为这样的情况发出警告,但正式来说这不是错误。