程序在运行的时候可能产生各种可预料到的异常,例如磁盘不足,内存不足,或是数学运算溢出,数组越界之类的。为了解决这些问题,C++提供了异常处理机制,它一般是由try语句和catch语句构成。
一、try和catch语句
示例代码如下:
首先我们定义了一个函数用于相除,假如被除数等于零就抛出异常。此时可以看到函数的定义后面多了一个throw(int)语句,这是用于强调此函数会抛出一个int类型的异常,当然不加也可能抛出各种类型。当我们输入b为零时,cal就会抛出0,而cal函数内并没有catch语句来捕捉异常,所以cal函数强行停止。cal函数抛出的异常在main函数中被catch语句捕捉到(注意到catch(int)表示捕捉int类型的抛出,另外,我们可以同时使用多个catch来捕捉多种类型的异常),于是会执行catch内的代码块。当然假若我们在cal函数中抛出的是一个double类型,那么main函数的catch就无法完成捕捉,程序会直接崩溃。也就是说,throw抛出的类型要和catch所能捕捉的类型一致。代码运行结果如下:
假如我们连续调用了几个函数,当最底层函数抛出了异常,它会首先在自身中寻找catch语句的捕捉,如果不能完成捕捉就会将异常抛出到调用它的上一层的函数,如果依旧不能,则继续向上抛出,以此类推...,这个便是异常的栈展开:
二、异常类
假如只是抛出一个int类型,我们只是知道有异常抛出,并不能知道更多的信息。但我们若只是抛出一个类的话,就可以在类中添加丰富的信息了。如以下代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 class myException{ 5 private: 6 char* s; 7 public: 8 myException(char* _s){ 9 s = _s; 10 }; 11 char* what(){ 12 return s; 13 } 14 15 16 }; 17 double cal(double a, double b){ 18 if(b == 0) throw myException("b is 0"); 19 if(a == 0) throw myException("a is 0"); 20 return a / b; 21 } 22 int main(int argc, char const *argv[]) 23 { 24 double a, b; 25 while(cin >> a >> b){ 26 try{ 27 cout << cal(a, b) << endl; 28 } 29 catch(myException &e){ 30 cout << e.what() << endl; 31 } 32 } 33 return 0; 34 }
我们定义了一个异常类,当产生异常时可以调用构造函数将异常信息传给数据成员s,然后被catch捕捉时可以调用成员函数what()来输出异常信息。程序运行结果如下:
//End.