一、原理
try{
//1:抛出异常的代码
//2:代码
}catch(){
//3:代码
//4:抛出异常
}finally{
//5:代码
}
//6:代码
首先要明确的一点是:不管try是否抛出异常,finally语句块都会执行。
整个try,catch,finally执行有以下几种情况:
1:try语句块没有抛出异常。如果是这种情况,程序会执行try,finally以及finally块之后的代码;
2:try语句块抛出了异常并且catch有匹配的异常。当遇到try里面抛出的异常后,try块里面剩下的代码就不执行了,跳转到catch块里面。
这里又可以分为2种情况。第一种,抛出的异常被后面的catch捕获,而catch又没有抛出新的异常,那么执行顺序是1356 ;第二种,如果catch里面又抛出新的异常,顺序是1345,然后将新的异常返回给方法调用者,6就不执行了 ;
3:try语句块抛出了异常,但是后面的catch没有能匹配的异常。那么会执行try和finally里面的语句也就是15,然后将该异常返回给方法调用者,不执行6 。
总结:
如果异常不能被捕捉的话,finally{}后面的语句就不会执行了,而finally{}一定被执行
二、实例
1、经典实例
#include "iostream"
using namespace std;
typedef struct tagPoint
{
int x;
int y;
}Point;
static void func(int n)
{
throw 1;
}
static void func(Point point)
{
Point p;
p.x=point.x;
p.y=point.y;
throw p;
}
int main()
{
Point point;
point.x=0;
point.y=0;
try
{
//func(point);
func(1);
}
catch (int e)
{
printf("int异常:%d\n",e);
}
catch (Point e)
{
printf("point异常:(%d,%d)\n",e.x,e.y);
}
return 0;
}
2、异常处理方式
#include<iostream>
using namespace std;
void service()throw(const char*)
{
int x;
cout<<"input integer(0:normal):";
cin>>x;
if(x!=0){
throw "in service throw exception";
}
cout<<"service execute normal..."<<endl;
}
void print(string name)throw()
{
cout<<name<<endl;
}
void service2()
{
int x;
cout<<"input integer:";
cin>>x;
if(x==0){
throw 100;
}
else if(x==1){
throw 3.14;
}
else if(x==2){
throw "x==2";
}
else{
cout<<x<<endl;
}
}
void service3()throw()
{
throw "service3 exception";
}
int main()
{
int x;
cout<<"input integer(0:normal,1:except):";
cin>>x;
if(x!=0){
throw 100;
}
try{
service();
}
catch(const char* e){
clog<<"handle const char* exception"<<endl;
clog<<e<<endl;
}
try{
service2();
}
catch(int e){
cerr<<"int exception"<<e<<endl;
}
catch(double e){
cerr<<"double exception"<<e<<endl;
}
catch(const char* e){
cerr<<"const char* exception"<<e<<endl;
}
catch(...){
cerr<<"... exception"<<endl;
}
try{
service3();
}
catch(const char* e){
cout<<e<<endl;
}
cout<<"program execute nomal..."<<endl;
}
3、异常传递
//异常传递(判断任意随机数是否是偶数)
#include<iostream>
#include"time.h"
using namespace std;
void f4()throw(const char*){
int x;
srand(time(NULL));
x=rand()%2;
if(x==0){
throw "出事了";
}
cout<<"f4运行正常"<<endl;
}
void f3()throw(const char*){
try{
f4();
}
catch(const char* e){
cout<<"f3处理f4的异常"<<endl;
throw;
}
}
void f2()throw(int){
try{
f3();
}
catch(const char* e){
clog<<"f2处理f3的异常"<<endl;
throw 12345;
}
}
void f1()throw(int){
try{
f2();
}
catch(int e){
clog<<"f1处理f2的异常"<<e<<endl;
throw;
}
}
int main()
{
try{
f1();
}
catch(int e){
clog<<"系统异常,请稍后再试..."<<endl;
}
}
4、函数覆盖时抛出异常
//函数覆盖时抛出异常
#include<iostream>
using namespace std;
class A{
public:
virtual void f(){}
virtual void g()throw(int,double){}
virtual void h()throw(int,double){}
virtual void j()throw(int,double,const char*){}
};
class B:public A{
public:
virtual void f()throw(int){}
virtual void g()throw(double){}
virtual void h()throw(int,double){}
virtual void j()throw(int,double,const char*){}
};
int main()
{
B b;
b.f();
}
5、自定义异常处理方式
//自定义异常处理方式
#include<iostream>
using namespace std;
//业务异常
class ServiceException:public exception{
public:
virtual const char* what()const throw()=0;
};
//登录异常
class LoginException:public ServiceException{
public:
virtual const char* what()const throw()
{
return "登录异常";
}
};
//转账异常
class TransferException: public ServiceException{
exception& e;
public:
TransferException(exception& e):e(e){}
virtual const char* what()const throw(){
string r=e.what();
return ("转账异常,原因:"+r).c_str();
}
//返回导致本异常的异常
exception getCause(){
return e;
}
};
//输入输出异常
class IOException:public exception{
public:
virtual const char* what()const throw(){
return "输入输出异常";
}
};
//数据库访问异常
class SQLException:public IOException{
public:
virtual const char* what()const throw(){
return "数据库访问异常";
}
} ;
//文件为找到异常
class FileNoFoundException:public IOException{
public:
virtual const char* what()const throw(){
return "文件未找到异常";
}
};
int main()
{
try{
cout<<"执行try"<<endl;
}
catch(FileNoFoundException* e){
clog<<"file not found"<<endl;
cerr<<e<<endl;
}
/*finally{
cout<<"in finally"<<endl;
}*/
cout<<"end..."<<endl;
}