C++异常处理
C++异常处理机制由三部分组成,即检查(try)、抛出(throw)、和捕捉(catch)。把需要检查的语句放在try中,throw用来当出现异常是抛出异常信息,而catch则用来捕捉异常信息。
一个简单的例子:
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
double triangle(double,double,double);
double a,b,c;
cin>>a>>b>>c;
try //在try中包含要检查的函数
{
while(a>0&&b>0&&c>0)
{
cout<<"the area is :"<<triangle(a,b,c)<<endl;
cin>>a>>b>>c;
}
}
catch(double)//用catch捕获异常信息,并做出相应处理
{
cout<<"a="<<a<<",b="<<b<<",c="<<c<<",that is not a triangle!"<<endl;
}
cout<<"end"<<endl;
}
double triangle(double a,double b,double c)
{
double s=(a+b+c)/2;
if(a+b<=c||a+c<=b||b+c<=a)throw a;//当不满足三角形两边之和大于第三边的时候,抛出异常
return sqrt(s*(s-a)*(s-b)*(s-c));
}当用户输入的数据不满足,两边之和大于第三边的时候,抛出异常,然后进行处理。
就单纯看这个例子的话,异常处理机制的用处并不大,因为处理还不如在triangle函数中直接给出警告简洁。
但是在一个大的系统那个中,包含许多模块,每个模块又包含很多函数,函数之间又相互调用,比较复杂。如果在每一个函数中都设置处理异常的程序段,会使程序过于复杂和庞大。
因此,如果在执行一个函数过程中,出现异常,可以不在本函数中立即处理,而是抛出一个异常,传给它的上一级(即调用它的函数),它的上级可以选择处理该异常,或者再往它的上级传递,如此逐级上升,如果最高一级还是无法处理,就调用系统函数terminate,使程序终止运行。
下面看个稍微复杂的例子:
#include<iostream>
using namespace std;
int main()
{
void f1();
try
{
f1(); //在main函数中调用f1
}
catch(double)
{
cout<<"ERROR_MAIN"<<endl;
}
cout<<"END_MAIN"<<endl;
return 0;
}
void f1()
{
void f2();
try
{
f2(); //在f1中调用f2
}
catch(char)
{
cout<<"ERROR_F1"<<endl;
}
cout<<"END_F1"<<endl;
}
void f2()
{
void f3();
try
{
f3(); //在f2中调用f3
}
catch(int)
{
cout<<"ERROR_F2"<<endl;
}
cout<<"END_F2"<<endl;
}
void f3()
{
double a=2.0;
try
{
throw a;
}
catch(float)
{
cout<<"ERROR_F3"<<endl;
}
cout<<"END_F3"<<endl;
}运行结果:
ERROR_MAIN
END_MAIN
(1)f3函数在try部分抛出异常,但是不符合f3的catch,于是依次往上级找,直到找到了main函数中的catch函数,由main中的catch进行处理。
(2)如果将f3函数改为:
void f3()
{
double a=2.0;
try
{
throw a;
}
catch(double)
{
cout<<"ERROR_F3"<<endl;
}
cout<<"END_F3"<<endl;
}输出结果为:
ERROR_F3
END_F3
END_F2
END_F1
END_MAIN
f3函数中throw的异常信息立即被f3函数中的catch子语句捕获。于是执行catch子句中的语句,再执行catch后面的语句,执行完了之后,f3函数执行结束后,流程返回f2函数中调用f3函数继续向下执行。
(3)如果将f3函数改为:
void f3()
{
double a=2.0;
try
{
throw a;
}
catch(double)
{
cout<<"ERROR_F3"<<endl;
throw;
}
cout<<"END_F3"<<endl;
}输出结果为:
ERROR_F3
ERROR_MAIN
END_MAIN
f3函数中的catch语句捕捉到抛出的异常之后,输出ERROR_F3,表示收到该异常,但它又立即用throw将a再次抛出。最后别main函数中的catch语句捕获。
浙公网安备 33010602011771号