异常处理-2

1、异常类

      异常可以是任意类型,包括你自己创建的类型。事实上,在实际程序中,大多数异常的类型都是类,而不是内置数据类型。为异常定义一个类的最好理由是:你可以创建一个类来描述“发生的错误信息”,而这个信息可以帮助“异常处理模块”处理错误。下面的代码说明了异常类的用法:

//使用异常类 #include <iostream.h> #include <string.h> class MyException { public: MyException() { *str_what='/0'; } MyException(char *s) { strcpy(str_what,s); } public: char str_what[80]; }; void main() { int a,b; try { cout<<"Enter numerator and denominator:"; cin>>a>>b; if(!b) throw MyException("Cannot divide by zero!"); else cout<<"Quotient is:"<<a/b<<endl; } catch(MyException e) { cout<<e.str_what<<endl; } } //输出结果: Enter numerator and denominator:2 0 Cannot divide by zero!

该程序提示用户输入一个分子和分母。如果分母是0,将抛出一个MyException类型的对象,指明发生了除0错误。也就是说,在MyException类型的对象中包含了错误信息。然后异常处理模块将使用这个信息告诉用户发生了什么错误。

      当然,在实际使用中使用的大多数异常类远比MyException要复杂。通常,你会创建一个定义了足够错误信息的类,这样就使得“异常处理模块”能够有效的响应甚至可能修复这种错误。

1.1、使用多个catch语句

      前面说过,一个try代码块可以有多个catch语句。实际上,这种做法很普遍。然而,每个catch语句所能捕获的异常类必须是不同类型。例如:下面的程序可以捕获“整数”和“字符指针”类型的异常:

//使用异常类 #include <iostream.h> #include <string.h> void Xhandler(int test) { try { if(test) throw test; else throw "value is zero."; } catch(int i) { cout<<"Caught one! Ex. #:"<<i<<endl; } catch(char *str) { cout<<"Caught a string:"<<str<<endl; } } void main() { cout<<"Start"<<endl; Xhandler(1); Xhandler(2); Xhandler(0); Xhandler(3); cout<<"End"<<endl; } 输出结果: Start Caught one! Ex. #:1 Caught one! Ex. #:2 Caught a string:value is zero. Caught one! Ex. #:3 End  

从输出的结果可以看到,每个catch语句仅响应与自己定义的类型相匹配的异常。通常,程序按照catch语句在程序中的顺序来检查每个catch语句,只能有一个匹配的catch语句被执行,而其它语句被忽略。

1.2、捕获基类的异常

      如果在多个catch语句中定义的“异常类型”之间存在派生关系,那么有一点很重要:如果某个catch语句能够捕获基类的异常,那么它也能够捕获派生类型的异常,那么应该将“捕获派生类型异常的catch语句”放在catch系列语句的前面。如果不这样做,那么捕获基类型异常的catch语句将捕获所有基类型和该基类型的派生类型的异常。而捕获派生类型异常的catch语句则被忽略,如下面的程序代码:

//使用异常类 #include <iostream.h> #include <string.h> class B { }; class D : public B { }; void main() { cout<<"Start"<<endl; D derived; try { throw derived; } catch(B b) { cout<<"Caught a base class."<<endl; } catch(D d) { cout<<"This won't execute."<<endl; } cout<<"End"<<endl; } //输出结果 Start Caught a base class. End  

在上面的程序中,由于对象drived的类是D,而D的基类又是B,所以它将被第一个catch语句所捕获,而第二个catch语句将永远不会执行。对于这种情况,编译器将会产生一个警告信息,在这种情况下,修改错误的方法是将catch语句的顺序调过来。

 

 

你可能感兴趣的:(异常处理-2)