二十一天学通C++之异常概述
二十一天学通C++:异常概述
本人节选自《21天学通C++》一书
简单地说,异常就是程序在运行过程中,由于使用环境的变化及用户的操作而产生的错误。例如,内存不足时,应用程序请求分配内存,程序中出现了以零为除数的错误;打印机未打开,导致程序运行中挂接这些设备失败等,都会引发异常。对这些错误,应用程序如果不能进行合适的处理,将会使程序变得非常脆弱,甚至不可使用。
因此,对于这些可以预料的错误,在程序设计时,应编制相应的预防代码或处理代码,以便防止异常发生后造成严重后果。一个应用程序,既要保证其正确性,还应有容错能力,或者说,既要在正确的应用环境中,在用户正确操作时,要运行正常、正确,并且在应用环境出现意外或用户操作不当时,也应有合理的反应。
因此,异常处理对于编写健壮的软件来说无疑是非常重要的,是否有完善的异常处理机制也是评价某一程序设计语言优劣的一个重要标准。
20.1.2 异常处理的基本思想
事实上,所有的程序设计语言对于异常处理的思想基本上都是类似的。简单地说,就是捕获异常后进行处理。
具体地说,处理异常的基本思想是:在底层发生的问题,逐级上报,直到有能力可以处理异常的那级为止。或者说,在应用程序中,如果某个函数发现了错误并引发异常,这个函数就将该异常向上级调用者传递,请求调用者捕获该异常并处理该错误。如果调用者不能处理该错误,就继续向上级调用者传递,直到异常被捕获错误被处理为止。
如果程序最终没有相应的代码处理该异常,那么该异常最后被C++系统所接受,C++系统就简单地终止程序运行。异常的传递如图20-1所示。
由图20-1读者可以看出,C++异常处理的目的是在异常发生时,尽可能地减少破坏,使得其不影响或尽量少地影响程序其他部分的运行。
提示:总的来说,对于小型程序和大型程序出现异常时,其处理的思想和方法稍有区别。一般来说,当小型程序在出现异常时,则将程序立即中断运行,无条件释放所有资源。
【范例20-1】异常处理的基本思想。该范例实现当除数为零时,停止运行并给出提示信息,实现代码如代码清单20-1所示。
代码清单20-1
1 #include<iostream.h> //包含头文件
2 #include<stdlib.h>
3 double fuc(double x, double y) //定义函数
4 {
5 if(y==0) //除数为0
6 {
7 cerr<<"error of dividing zero./n"; //输出错误信息
8 exit(1); //异常退出程序
9 }
10 return x/y; //返回两个数的商
11 }
12 void main()
13 {
14 double res;
15 res=fuc(2,3); //调用函数
16 cout<<"The result of x/y is : "<<res<<endl; //输出正确结果
17 res=fuc(4,0); //除数为0发生异常
18 cout<<"The result of x/y is : "<<res<<endl; //不执行该语句
19 }
【运行结果】同样的,在Visual C++中新建一个【C++ Source File】文件,输入上述的代码,编译无误后运行。
【范例解析】上述代码中,定义了函数fuc(),用于返回两个数的商,并处理当除数为0时的异常,在主函数main()中第17行调用fuc()函数时出现了一个除数为0的异常,其并不输出两个数的商,而是调用代码中第4~9行的异常处理,输出错误信息并异常退出程序。
注意:exit()函数用于退出程序,该函数可加参数,其中exit(0)表示正常退出程序,而exit(1)表示异常退出程序。
当然,如果是在大中型程序中,上述处理方法就过于简单。这是因为在大中型程序中,函数之间有着明确的分工和复杂的调用关系。由于在这些程序中,发现错误的程序往往在函数调用链的底层,如果简单地在发现错误的函数中处理异常,就没有机会把上层函数已经完成的一些工作做妥善的处理。