异常处理
什么是异常:不常发生但无法避免。
返回错误码
设置errno全局变量
抛出异常
捕获异常:
用Try{}把可能发生异常的代码包起来紧跟其后用若干个(至少一个)catch(类型 e){}来捕获指定类型的异常并处理,处理后程序从最后一个catch块后继续运行。
抛出异常:throw 数据;
被Throw拋出的异常数据不受作用范围的限制,直到被捕获被处理为止,因此在捕获时可以通过引用来访问异常数据。即使已经被处理的异常数据,也可以用一个不带数据的throw重新抛出。
如果抛出的异常没有被捕获处理,系统会调用terminate()函数终止程序。set_terminate(fun)可以指定在terminate时自动调用func函数。
异常传递机制:从throw开始离开正常执行流程,在本函数内找有没有包含它的try{}块,如果有依次查找它的catch块直到第一个类型匹配的为止进入这个catch块执行处理,之后从最后一个catch块之后继续执行;如果没有包含它的try{}块或者没有类型匹配的catch块,异常数据继续传递到上层函数(调用它的那个函数)中重复这个过程,如果直到Main函数还没有处理,就会传递给内核,系统就会调用terminate终止程序
多个catch块如果同时有父类类型和子类类型,应该把子类类型放在前面,如果有一个是catch(...),它必须放在最后。
#include<iostream> using namespace std; #include<string> void f1() { try{ cout<<"1--int\n2--double\n0--return\n"; int n; cin>>n; if(n==1) throw 1; if(n==2) throw 2.2; if(n==0) return; throw string("error"); } catch(long e){cout<<"long "<<e<<endl;} catch(double e){cout<<"double "<<e<<endl;} cout<<"----endl of f1----"<<endl; } void f2() { try{ f1(); cout<<"----in f2----"<<endl; } catch(int e){cout<<"int "<<e<<endl;} cout<<"----end of f2----"<<endl; } int main() { try{ f2(); } catch(...) {cout<<"发生异常"<<endl;} cout<<"我还会回来的"<<endl; system("pause"); }
异常申明:一个函数可以声明自己可能抛出哪些类型的异常,格式为
返回类型 函数名(参数表) throw(异常类型列表);
int func(int a[],int idx) throw(double,int,string);
如果在函数内部抛出了不在列表中的异常,则会引发意外。unexpected 可以通过set_unexpected(func)来设置遇到意外的情况时调用func来设置遇到意外情况时调用func.没有异常声明表示可能抛出任何类型的异常,空异常列表表示不会抛出异常
#include<iostream> using namespace std; #include<exception> void f1(int n)throw(int,double) { try{ if(n==1) throw 123; if(n==2) throw 4.5; throw "out of range"; } catch(int e){ cout<<"catch "<<e<<" in f1"<<endl; if(e>100) throw;//重新抛出当前异常数据 } } void func(){cout<<"异常类型不在列表中"<<endl;} int main(int argc,char* argv[]) {//argument参数,cont数量,vector不定长数组 set_unexpected(func); try{ cout<<"argc="<<argc<<endl; f1(argc); } catch(int e){cout<<"int "<<e<<endl;} catch(double e){cout<<"double "<<e<<endl;} //catch(...){cout<<"exception"<<endl;} system("pause"); }
标准异常:exception类,#include<exception>
定义子类覆盖父类的虚函数时,异常声明的内容不能超出父类中异常声明的内容
标准库中抛出的异常类型都是exception的子类
自己定义异常类型一般继承exception类,覆盖const char* what() const throw()函数,返回一个字符串,描述发生了什么异常
#include<iostream> using namespace std; #include<exception> #include<new> #include<cstdio> class A{//数组类 int *p; int len; public: explicit A(int n) throw(){ p = new (nothrow) int[n]; len = n; } int& operator[](int index){ if(index<0) throw NegIndex(index); if(index>=len) throw OutofRange(index); if(p==NULL) throw MemoryException(); return p[index]; } class NegIndex : public exception{ int i; public: NegIndex(int index)throw():i(index){}; const char* what()const throw(){ static char buf[100]; sprintf(buf,"负下标异常%d",i); return buf; } }; class OutofRange : public exception{ int i; public: OutofRange(int index)throw():i(index){}; const char* what()const throw(){ static char buf[100]; sprintf(buf,"越界%d",i); return buf; } }; class MemoryException : public exception{ public: const char* what()const throw(){ return "内存不足"; } }; }; int main() { A x(10); x[0] =5,x[3]=10,x[8]=20; cout<<x[3]*x[0]*x[8]<<endl; cout<<x[-5]<<endl; cout<<x[20]<<endl; system("pause"); }