(1)在匹配的过程中,不会将一种异常类型自动转换为另一个中异常。
class Exception1
{};
class Exception2
{
public:
Exception2(const Exception1&) {}
};
void f()
{
throw Exception1();
}
int _tmain(int argc, char* argv[])
{
try
{
f();
}
catch(Exception2&)
{
cout<<"inside catch(Exception2&)"<<endl;
}
catch(Exception1&)
{
cout<<"inside catch(Exception1&)"<<endl;
}
return 0;
}
尽管在Exception2中有一个从Exception1到Exception2的转换构造函数,但是在匹配的过程中并不执行,而是进入匹配Exception1的异常处理器。
(2)通过基类的引用,可以捕获基类异常及其派生类的异常。
class X
{
public:
class Trouble {};
class Small:public Trouble {};
class Big:public Trouble {};
void f() {throw Big();}
};
int _tmain(int argc, char* argv[])
{
X x;
try
{
x.f();
}
catch(X::Trouble&)
{
cout<<"catch Trouble"<<endl;
}
catch(X::Small&)
{
cout<<"catch Small"<<endl;
}
catch(X::Big&)
{
cout<<"catch Big"<<endl;
}
return 0;
}
以上输出catch Trouble。
通常的做法:首先捕获派生类的异常,并且将基类放到最后用于捕获其他不太具体的异常。
(3)函数级try块。
class Base
{
public:
class BaseExcept {};
Base(int ii):i(ii) {throw BaseExcept();}
private:
int i;
};
class Derived:public Base
{
public:
class DerivedExcept
{
const char* msg;
public:
DerivedExcept(const char* msg):msg(msg) {}
const char* what() const {return msg;}
};
Derived(int j)try:Base(j)
{
cout<<"This won't print"<<endl;
}
catch(BaseExcept&)
{
throw DerivedExcept("Base subobject threw");
}
};
int _tmain(int argc, char* argv[])
{
try
{
Derived d(3);
}
catch(Derived::DerivedExcept& d)
{
cout<<d.what()<<endl;
}
return 0;
}
上述派生类的构造函数就用了函数级的try块,这样的用法可以捕捉基类或者成员对象在构造过程中抛出的异常。构造函数的函数体就是try块,异常处理器在函数体外。