C++ 异常机制
来源:互联网 发布:2013网络歌手 编辑:程序博客网 时间:2024/05/16 15:23
一,C++异常机制的作用
C++异常是对程序在运行过程中发生异常情况的一种响应,异常提供了将程序的控制权从程序的一部分传递到另一部分的响应。异常的抛出和处理主要使用了以下三个关键字: try、 throw 、 catch 。
(1)try:放在try块中的代码是可能发生异常的代码。
(2)throw:这个关键字引发异常,紧随其后的值指出了异常的特征。throw语句实际上是跳转,即命令程序跳到另一语句。throw语句必须包含在try块中,也可以是被包含在外层函数的try块中。
(3)catch:捕获异常,随后是位于括号中的类型声明,它指出了异常处理程序要响应的异常类型。
try-catch语句形式如下:
try{
包含可能抛出异常的语句;
}
catch(类型名 [形参名]){ // 捕获特定类型的异常
//异常处理程序
}
catch(...) { // 三个点则表示捕获所有类型的异常
//异常处理程序
}
二,使用异常机制处理异常
double fun(double x, double y){ if(y == 0){ throw y; //除数为0,抛出异常 } return x / y;}int main(){ double res; try{ res = fun(2, 0); } catch(double val){ cout<<"除数为:"<<val<<endl; exit(1); } return 0;}
三,使用自定义的对象作为异常类型
使用自定义的对象作为异常类型的优点:
1,可以使用不同的异常类型来区分引发不同的异常。
2,对象可以携带信息,程序员可以根据这些信息来确定引发异常的信息。
class bad_func{private: int v1;public: bad_func(int v1){ this->v1 = v1; } void mesg(){ cout<<"除数不能为:"<<v1<<endl; }};double fun(double x, double y){ if(y == 0){ throw bad_func(0); //除数为0,抛出异常 } return x / y;}int main(){ double res; try{ res = fun(2, 0); } catch(bad_func &exp){ exp.mesg(); exit(1); } return 0;}
四,栈解退
假设在try块没有直接调用引发异常的函数,而是调用了另外一个会引发异常的函数,则程序的流程将从引发异常的函数直接跳到包含try块和处理程序的函数,这涉及到栈解退。栈解退的过程如下:
如果一个函数由于异常而终止,程序将进行出栈的操作,但是不会在回退到栈的第一个返回地址后停止,而是继续回退栈,直到找到一个位于try块中的返回地址。然后控制权交给块尾的处理程序,而不是函数调用后的第一条语句,这个过程称为栈解退。
void funcA();void funcB();void funcC();void funcA(){ funcB();}void funcB(){ funcC();}void funcC(){ throw 0; //抛出一个异常}int main(){ double res; try{ funcA(); } catch(int val){ exit(1); } return 0;}
funcC()函数引发了一个异常,此时会回退到调用funcC()的funcB(),在funcB()中发现funcC()并没有放到try块中,即在funcB()中没有对异常进行处理;此时会回退到调用funcB()的funcA(),同样在funcA()中发现funcB()并没有放到try块中,此时会回退到调用funcA()的main()函数,在main()函数中funcA()是放在try块中,此时程序的控制权就跳转到main()函数中。
五,throw-catch语句与函数参数与函数返回机制的区别
(1),函数func()中的返回语句将控制权返回到调用func()的函数,但是throw语句将控制权向上返回到第一个这样的函数,即包含能够捕获异常的try-catch块。
(2),引发异常时编译器总是创建异常对象的一个临时拷贝,即catch块中的参数是引用类型。
class bad_func{private: int v1;public: bad_func(int v1){ this->v1 = v1; cout<<"bad_func构造函数"<<endl; } void mesg(){ cout<<"除数不能为:"<<v1<<endl; } bad_func(const bad_func &p){ this->v1 = p.v1; cout<<"bad_func复制构造函数"<<endl; } ~bad_func(){ cout<<"bad_func析构函数: "<<this<<endl; }};double fun(double x, double y){ if(y == 0){ bad_func obj(0); cout<<"bad_func对象地址: "<<&obj<<endl; throw obj; //除数为0,抛出异常 } return x / y;}int main(){ double res; try{ fun(2, 0); } catch(bad_func &p){ cout<<"bad_func对象地址: "<<&p<<endl; exit(1); } return 0;}
输出结果
bad_func构造函数bad_func对象地址: 0x69fe6cbad_func复制构造函数bad_func析构函数: 0x69fe6cbad_func对象地址: 0x6f0dc0bad_func析构函数: 0x6f0dc0Process returned 1 (0x1) execution time : 0.008 sPress any key to continue.
六,exception类
较新的C++编译器将异常合并到语音中。例如,为了支持该语言,exception头文件定义了exception类作为基类。其中有一个名为what()的虚函数,它返回一个字符串,该字符串的特征随实现而异。
class bad_func : exception{private: int v1;public: bad_func(int v1){ this->v1 = v1; cout<<"bad_func构造函数"<<endl; } bad_func(const bad_func &p){ this->v1 = p.v1; cout<<"bad_func复制构造函数"<<endl; } //重写虚函数what() const char* what(){ cout<<"除数不能为0."; }};double fun(double x, double y){ if(y == 0){ bad_func obj(0); cout<<"bad_func对象地址: "<<&obj<<endl; throw obj; //除数为0,抛出异常 } return x / y;}int main(){ double res; try{ fun(2, 0); } catch(bad_func &p){ cout<<"bad_func对象地址: "<<&p<<endl; p.what(); exit(1); } return 0;}
七,bad_alloc异常与new
使用new导致内存分配问题,C++的最新的处理方式是让new引发bad_alloc异常,头文件new包含bad_alloc的声明,它是从exception类公有派生而来的。但是在以前,当无法分配请求的内存量时,new返回一个空指针。
struct Big{ double stuff[200000];};int main(){ Big *p; try{ p = new Big[10000]; } catch(bad_alloc &p){ cout<<p.what()<<endl; exit(1); } cout<<"success."<<endl; return 0;}
八,C++在函数声明后面添加throw关键字
C++函数声明后面添加throw关键字,是对这个函数的异常安全性做出限制。
void fun() throw(); //表示fun不允许抛出任何形式的异常,fun是异常安全的。void fun() throw(...); //表示fun可以抛出任何形式的异常。void fun() throw(Type); //表示fun可以抛出Type类型异常。(1),函数后面声明 throw() 只是接口的提供者和接口的使用者间的默契或称协议。
(2),声明一个不抛出异常的函数后,你有责任保证在你的函数的实现里面不会抛出异常。
(3),对于一个抛出指定抛出异常类型的函数,实际抛出的异常要与指定的异常一致。
void getName() throw(double){ int num = 5; throw(num);}int main(){ try{ getName(); } catch(int){ cout<<"catch error."<<endl; }}程序分析:
上面声明了一个抛出double类型异常的函数,但是实际抛出的是int类型的异常。不论自己在catch块中捕获的是int类型还是double类型的异常,程序在运行期间都会终止运行。
- 【C/C++】异常机制
- C++‘异常’处理机制
- C ++ 异常机制
- Object-C异常机制
- 【C语言】异常--异常处理机制
- C语言异常机制处理
- C/C++异常处理机制
- C语言异常处理机制
- C/C++异常处理机制
- 异常处理机制(JAVA&C#)
- [转载]C语言的异常机制
- C异常处理机制:setjmp和longjmp
- C语言中的异常处理机制
- C异常处理机制:setjmp和longjmp
- C异常处理机制:setjmp和longjmp
- object-c的异常处理机制
- Objective-C语言:异常处理机制
- objective-c异常处理机制详解
- iOS学习笔记-057.自定义View04——刷帧动画
- 关于数组,sizeof(),strlen的计算问题
- Android复习-fragment声明周期与Activity生命周期(个人笔记)
- Linux3.2.81内核移植(2440)
- 其他,備忘
- C++ 异常机制
- eclipse中的java工程项目如何引用外部jar包和dll动态链接库?
- 二叉树建立 ---层次遍历方式
- 用Vue2.0实现tabbar
- 二分图匹配——Luogu2756 [网络流24题]飞行员配对方案问题
- 如何在Linux下快速安装MapTiler
- iOS could not load any Objective-C class information
- 解耦框架 ModularizationArchitecture 学习解析
- iOS学习笔记-058.绘制的多种方法——矩形