16.2.4 有继承关系的类异常

    在有继承关系的类异常捕获处理上,有条原则为对某个catch块来说,如果其参数列表中是基类的类型,则其总是可以捕获基类和其派生类的异常对象,而如果catch块的参数列表中是派生类型,不能捕获基类的异常对象。

    因此,为避免基类垄断的局面,推荐将用于捕获派生类的catch块写在上面,用于捕获基类的catch块写在下面,这保证了派生类先找到与其匹配的异常处理catch块,而最后再由基类找到与其匹配的catch块。

    如示例代码16.6所示。

    代码16.6 有继承关系的类异常处理ExceptionInheritance


    <——————————-文件名:example1606.cpp————————————————> 01 #include<iostream> 02 using namespace std; 03 class Exception1 04 { 05 }; 06 class Exception2:public Exception1//派生类定义 07 { 08 }; 09 void fun() 10 { 11 cout<<"请输入一个整数大于0,基类异常被抛出, 12 在其他情况下,派生类异常被抛出"<<endl; 13 int num=0; 14 cin>>num; 15 if(num>0) 16 throw Exception1();//抛出Exception1类型的异常(默认的构造函数) 17 else 18 throw Exception2();//抛出Exception2类型的异常(默认的构造函数) 19 } 20 int main() 21 { 22 try 23 { 24 fun(); 25 } 26 catch(Exception1&Ex) 27 { 28 cout<<"由基类异常处理程序捕获"<<endl; 29 } 30 catch(Exception2&Ex)//引用传递而不是值传递 31 { 32 cout<<"由派生类异常处理程序捕获"<<endl; 33 } 34 return 0; 35 }

    输出结果如下所示。


    请输入一个整数大于0,基类异常被抛出,在其他情况下,派生类异常被抛出 -3(用户输入) 基类异常被引发

    【代码解析】代码中即使输入了小于0的数-3,仍然是由基类异常处理程序来捕获的,这是因为代码16.6写错了catch块的顺序,因为代码第26行的catch(Exception1&Ex)不仅可以捕获基类Exception1的对象,同样可以捕获派生类Exception2的对象,后面的仅用于捕获派生类对象的catch(Exception2&Ex)语句实际上被架空了,解决的办法是将两个catch块的顺序进行调换。