在异常类的层级结构中,应按照从最派生到基类的顺序排列catch语句,以允许捕获异常类层级中多个类的异常。
我的答案是基于Linux编译器,但希望对所有编译器都适用。catch的顺序取决于两个因素:
(1) 先来先选;如果基类出现在派生类之前,则会选择基类。有些编译器会警告此情况,有些则不会;
(2) 继承类型;即公共或非公共(私有/保护)。
struct B {};
struct D : B {};
struct DD : D {};
int main()
{
for(int i = 0; i < 3; i++)
{
try
{
switch(i)
{
case 0: throw new B;
case 1: throw new D;
case 2: throw new DD;
}
}
catch(B *o) { cout<<"B* caught\n"; }
catch(D *o) { cout<<"D* caught\n"; }
catch(DD *o) { cout<<"DD* caught\n"; }
}
}
(1)在上面的代码中,它总是捕获B。如果您更改为捕获DD、D、B的顺序,则会按照您的期望给出派生类。
(2)现在将“struct”替换为“class”,或将继承更改为private/protected;在上述代码中,无论顺序如何,catches都将匹配throw的类型。它将非常严格,即使您删除Derived类的任何catch,也不会被Base类捕获。
throw new Foo;
或者catch (Foo*)
。通过值抛出并通过(const)引用捕获(throw Foo();
,catch (Foo const&)
)。 - Max Truxa正确的顺序应该是最派生的先。处理程序必须按照从最派生类到基类的顺序排列。
这里是一个代码示例:
#include <iostream>
using namespace std;
class MyException
{
public:
MyException(int value):mValue(value)
{
}
int mValue;
};
class MyDerivedException: public MyException
{
public:
MyDerivedException(int value, int anotherValue):MyException(value),mAnotherValue(anotherValue)
{
}
int mValue;
int mAnotherValue;
};
void doSomething()
{
//Lot of Interesting stuff
//Exception condition
throw MyDerivedException(10,20);
}
int main()
{
try
{
doSomething();
}
catch(MyDerivedException &exception)
{
cout<<"\nCaught Derived Class Exception\n";
}
catch(MyException &exception)
{
cout<<"\nCaught Base Class Exception\n";
}
return 0;
}