异常(C++中的异常处理)
一、传统错误的处理方式:
1、终止程序(除数为0)
2、返回一个标识错误的值,附加错误码(GetLasrError)
执行下述代码,若是该文件不存在,会出现错误,
方式1:直接从监视窗口输出错误:
方式2:工具---错误查找---输入错误值---即可查看错误原因
3、返回一个合法值,让程序处于某种非法的状态(坑爹的atoi())
atoi把用户类型的字符串转换为整型的数据,从字符串第一个位置开始依次往后找,直到遇到第一个非字符串的数字终止。
4、调用一个预先注备好在出现“错误”的情况下用的函数(回调函数)
回调函数:函数是自己写的,但是不一定是自己调用-
5、暴力解决方式:abort()或者exit():代码会终止
6、使用goto语句:事件发生后跳转到某一个位置,根据具体的标签跳到不同的位置(指定的标签的位置),一般不提倡使用goto,打乱了程序正常执行的流程。【共同只能在当前函数作用域中跳转,不能跳出当前函数的作用域】
http://www.baidu.com在C语言中相当于:http:是一个标签; //是一个注释【把要显示的东西当作一个链接来显示,但是在编译阶段被当成语法进行检测,只是一个标签后面跟着一个注释】
7、setjmp()和longjmp():长调转,可以从一个函数里面跳转到另一个函数的位置
把错误处理代码放到一个统一的位置进行处理,把正常代码和错误处理代码划分开了
setjump必须先调用,在异常位置通过调用longjmp以恢复先前被保存的程序执行点,否则将导致不可预测的结果,甚至程序崩溃 在调用setjmp的函数返回之前调动longjmp,否则结果不可预料
二、c++中对异常的处理,先将异常的地方抛出(用throw关键字抛出异常),并且发生异常的代码要进行捕获。
(1)异常是通过抛出对象而引发的,该对象的类型决定了应该激活哪个处 理代码
a、抛出的字符类型的异常,整型不可以捕获到,说明没有进行类型转化,最后会导致程序崩溃。
产生申请空进失败(存储空间不足,无法处理此命令)
b、对字符类型的异常也要进行捕获,以下代码会成功
2、被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最 近的那一个
(1)下面程序对malloc抛出的异常进行了两次捕获,一次在TestMalloc函数里面,一次在main函数里面,
先捕获到TestMalloc函数体里面的异常,此时异常捕获到之后,抛出异常,说明异常已经被处理了
(2)在整型类型的捕获中添加对字符类型的捕获,此时不匹配,
此时TestFile函数没有捕获到异常,但是main函数捕获到了异常
3、抛出异常后会释放局部存储对象,所以被抛出的对象也就还给系统了,throw表达式会初始化一个抛出特殊的异常对象副本(匿名对 象),异常对象由编译管理,异常对象在传给对应的catch处理之后撤销
(1)函数抛出异常,说明函数已经返回了,是以一种异常的方式退出的,类似于运行结束,应该将函数中的栈、对象等清理掉
说明清理了栈上的空间
(2)副本:将整型异常1换为拷贝构造函数出的对象a
打印外部函数a的地址和主函数中异常抛出的对象的地址,最后一个析构函数析构的是抛出异常对象的副本
三、栈展开
在主函数中就拦截了异常,则异常就不存在了。主函数是最后一次捕获异常的机会,出了主函数就跑到了操作系统中,使操作系统崩溃。
四、异常捕获的匹配规则
异常对象的类型与catch说明符的类型必须完全匹配
(1)允许从非const对象到const的转换
结果可以进行捕获
(2)允许从派生类型到基类类型的转换
结果可以捕获到
(3)将数组转换为指向数组类型的指针,将函数转换为指向函数类型的指针
结果可以捕获
抛出函数异常
有可能单个的catch不能完全处理一个异常,在进行一些校正处理以后,希望再交给更外层的调用链函数来处理,catch则可以通过重新抛出将异常传 递给更上层的函数进行处理
1、对于以下代码,如果TestFunc0()存在异常TestFunc1()没有进行捕获,delete语句不会执行,空间不能释放,代码存在内存泄漏。
捕获TestFunc0()中的异常,将空间释放掉。不是自己函数中的异常,不用管是什么类型
catch (...)
{
delete[] p;
return;
}中异常不用处理,因为不知道具体是什么类型的异常,将异常继续抛出。在主函数中将异常进行捕获
六、异常规范:在c++11中已经取消了
(1)当前函数抛出异常,只能抛出整型和double类型的异常,抛出其他类型的异常,编译器会报错
一般都会维护一个自己的异常体系结构
下述代码的复杂程度较高,遇到中途退出的情况都需要关闭文件描述符、释放资源,使代码的结构更复杂。
此时我们可以使用资源分配的初始化来让程序自己去控制在不需要资源时,自动将资源归还给系统。
下一篇博客会详细描述。
浙公网安备 33010602011771号