1、异常处理的基本思想
目标:使用软件具有容错能力。在出现异常时程序能够继续往下运行,必要时提供错误信息。
软件开发中往往每个函数都有自己的分工,很多出现错误的函数都不会处理错误,而是产生一个异常让调用者捕捉和处理。如果调用者也不能处理此异常,则异常就会被继续向上级调用者传递,这个传递过程会一直持续到异常能被处理为止。如果程序最终没能处理这个异常,那么它就会被传递给C++的库函数terminate,然后terminate会调用abort函数终止程序。
2、C+异常处理方法
try 、throw、catch语句
throw 表达式 //异常不能处理时,以该方式传递异常给调用者
try
{
复合语句 //被监测程序段
}
catch(异常类型的声明) //依次检查,哪个与抛出异常一致,则该catch处理异常
{
复合语句
}
catch(异常类型的声明)
{
复合语句
}
...
catch(…) //该catch能处理所有异常,只能放到try所有catch后
异常处理流程:
a、程序正常执行到try块的try子句,然后执行try子句后的复合语句,也就是被监测的程序段。
b、如果try子句后的程序段正常执行了,没有发生任何异常,那么此try块的所有catch子句将不被执行,程序直接跳转到整个try块(包括try子句和所有catch子句)后继续执行。
c、如果try子句后的程序段或者此程序段中的任何调用函数发生了异常,并通过throw抛出了这个异常,则此try块的所有catch子句会按其出现的顺序被检查。若没有找到匹配的处理程序则继续检查外层的try块。如果一直找不到则此过程会继续到最外层的try块被检查。
这里有两种结果:
1.找到了匹配的处理程序,则相应catch子句捕捉异常,将异常对象拷贝给catch的参数,如果此参数是引用则它指向异常对象。catch的参数初始化以后,此catch子句 对应的 try子句的程序段中,从开头 到 异常抛出 位置之间构造的所有对象进行析构,析构顺序与构造顺序相反。然后catch处理程序被执行,最后程序跳转到try块之后的语句执行。
2.始终没有找到匹配的处理程序,则运行C++库函数terminate,而terminate函数调用abort函数终止程序。
3、异常接口声明
void fun() throw(X,Y);
//fun函数能且只能抛出X、Y及它们的子类型异常
void fun()
//没有给出异常接口声明,此函数可能抛出任何异常
void func() throw();
//不抛出任何类型异常
#include<iostream>
#include"math.h"
using namespace std;
double Sqrt(double x); //求平方根声明
int main()
{
try
{
//被监测程序段
cout<<"9.0的平方根:"<<Sqrt(9.0)<<endl;
cout<<"-1.0的平方根:"<<Sqrt(-1.0)<<endl;
}
catch(double x) //捕捉double型异常
{
cout<<"负数错误"<<x<<endl;
}
return 0;
}
double Sqrt(double x)
{
if(x<0)
throw x; //抛出double型异常
else
return sqrt(x);
}