[转贴] 从零开始学C++之异常(二):程序错误、异常(语法、抛出、捕获、传播)、栈展开
一、程序错误
编译错误,即语法错误。程序就无法被生成运行代码。
运行时错误
不可预料的逻辑错误
可以预料的运行异常
例如:
动态分配空间时可能不会成功
打开文件可能会失败
除法运算时分母可能为0
整数相乘可能溢出
数组越界……
二、异常
(一)、异常语法
throw 表达式;
try
{
//try语句块
}
catch(类型1 参数1)
{
//针对类型1的异常处理
}
catch (类型2 参数2)
{
//针对类型2的异常处理
}
…
catch (类型n 参数n)
{
//针对类型n的异常处理
}
(二)、异常抛出
可以抛出内置类型异常也可以抛出自定义类型异常
throw抛出一个类对象会调用拷贝构造函数
异常发生之前创建的局部对象被销毁,这一过程称为栈展开
(三)、异常捕获
一个异常处理器一般只捕捉一种类型的异常
异常处理器的参数类型和抛出异常的类型相同
…表示可以捕获任何异常
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
#include <iostream>
#include <string> using namespace std; class MyException const char *what() const |
程序自定义一个异常类型MyException,从输出可以看出,Divide函数内先构造一个MyException对象e,调用构造函数,因为e是局部对象需要被析构,在析构前先调用拷贝构造函数构造另一个对象,这个对象将被catch 引用,最后这个对象在catch末尾也将被析构。
假设没有构造局部对象,直接throw , 如 throw MyException("division by zero"); 那么将不会调用拷贝构造函数,只存在一个对象,在catch的末尾被析构。
假设throw 1; 而没有对应的catch (int) ,即使存在catch (double) 也捕获不到,不会做类型转换,此时会由catch (...) 捕获到,...表示可以捕获任何异常。
(四)、异常传播
1、try块可以嵌套
2、程序按顺序寻找匹配的异常处理器,抛出的异常将被第一个类型符合的异常处理器捕获
如果内层try块后面没有找到合适的异常处理器,该异常向外传播,到外层try块后面的catch块中寻找
3、没有被捕获的异常将调用terminate函数,terminate函数默认调用abort终止程序的执行
可以使用set_terminate函数指定terminate函数在调用abort之前将调用的函数
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
void MyTerminate()
{ cout << "MyTerminate ..." << endl; } int main(void) |
其中MyException类如上,程序中将内层的catch (MyException& e) 屏蔽了,所以由外层的catch (MyException& e) 捕获,假设将两个都注释掉的话,因为没有找到合适的catch, 那么terminate 函数会被调用,并且由于事先set_terminate
函数设定了abort调用之前被调用的函数MyTerminate,故先输出MyTerminate ...然后程序被终止。
三、栈展开
沿着嵌套调用链接向上查找,直至为异常找到一个catch子句。这个过程称之为栈展开。
为局部对象调用析构函数
析构函数应该从不抛出异常
栈展开期间会执行析构函数,在执行析构函数的时候,已经引发的异常但还没处理,如果这个过程中析构函数又抛出新的异常,将会调用标准库的terminate函数。
异常与构造函数
构造函数中可以抛出异常。如果在构造函数函数中抛出异常,则可能该对象只是部分被构造。即使对象只是被部分构造,也要保证销毁已构造的成员。(如果成员是指针p,因为析构函数不会被调用,故不会执行一般的delete p; 很可能造成内存泄漏)
[转贴] 从零开始学C++之异常(二):程序错误、异常(语法、抛出、捕获、传播)、栈展开的更多相关文章
- Spring事务异常回滚,捕获异常不抛出就不会回滚(转载) 解决了我一年前的问题
最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了....... 为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志.但是这边情况来了,当这个方法异常 ...
- cocos2d-x 错误异常抛出捕获和崩溃拦截
Error对象 一旦代码解析或运行时发生错误,JavaScript引擎就会自动产生并抛出一个Error对象的实例,然后整个程序就中断在发生错误的地方. Error对象的实例有三个最基本的属性: nam ...
- C# 中异常抛出捕获机制--throw / try,catch,finally
try { messagebox.show("true"); } catch { messagebox.show("false"); } finally { m ...
- 从零开始学Electron笔记(二)
在之前的文章我们简单介绍了一下Electron可以用WEB语言开发桌面级应用,接下来我们继续说一下Electron的菜单创建和事件绑定. 我们接上一章的代码继续编写,上一章代码 https://www ...
- 从零开始学ios开发(二):Hello World!来啦!
今天看了书的第二章,主要介绍了一下Xcode的使用方法和一些必要的说明,最后做了一个“Hello World!”的小程序,其实就是在屏幕上用一个Label显示“Hello World!”,一行代码都没 ...
- 从零开始学ios开发(二十):Application Settings and User Defaults(下)
在上一篇的学习中,我们知道了如何为一个App添加它的Settings设置项,在Settings设置项中我们可以添加哪些类型的控件,这些控件都是通过一个plist来进行管理的,我们只需对plist进行修 ...
- 从零开始学安全(四十二)●利用Wireshark分析ARP协议数据包
wireshark:是一个网络封包分析软件.网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料.Wireshark使用WinPCAP作为接口,直接与网卡进行数据报文交换,是目前 ...
- 从零开始学Linux系统(二)之基本操作指令
ifconfigping ip地址帮助:ping -t ip地址ping -c 次数 ip地址ping -s 包的大小关机重启:shutdown -h now reboot清屏:clear == C ...
- 从零开始学ios开发(二):Hello World!
今天看了书的第二章,主要介绍了一下Xcode的使用方法和一些必要的说明,最后做了一个“Hello World!”的小程序,其实就是在屏幕上用一个Label显示“Hello World!”,一行代码都没 ...
- Spring事务异常回滚,捕获异常不抛出就不会回滚
最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了....... 为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志.但是这边情况来了,当这个方法异常 ...
随机推荐
- js 注册手机摇动事件
var rockModule = (function () { //监听手机摇动事件 if (window.DeviceMotionEvent) { window.addEventListener(' ...
- YII中的表单挂件
利用助手(widget)在页面实现表单 控制器中 <?php class YiiFormController extends Controller { public function actio ...
- C#测量程序运行时间及cpu使用时间
转载:http://www.cnblogs.com/yanpeng/archive/2008/10/15/1943369.html 对一个服务器程序想统计每秒可以处理多少数据包,要如何做?答案是用处理 ...
- 【JAVA错误笔记】 - c3p0问题java.lang.NoClassDefFoundError:com.mchange.v2.ser.Indirector
错误描述:java.lang.NoClassDefFoundError:com.mchange.v2.ser.Indirector 原因分析: 这是c3p0的一个错误信息,我们在下载 c3p0时候,z ...
- php注册登录时生成的验证码
http://blog.sina.com.cn/s/blog_8173443e01012l82.html 记得我学php时第一件事就是研究登陆注册.当然,登陆少不了验证码.两年过去了,昨天突然想用个验 ...
- JDBC对sql server的操作
1.过程: 1>注册驱动器类:Class.forName() 2>连接数据库: String url = "jdbc:sqlserver:// ...
- Asp.Net部分面试题
HTML.javascript部分 1. jQuery的美元符号$有什么作用? 答:个人理解:$指代jquery对象,拥有jquery对象所有的属性和成员 网友理解:在Jquery中,$是JQuery ...
- DBCP的配置参数
tomcatde DHCP的配置 <Resource driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver&quo ...
- 每天一条linux命令——shutdown
shutdown命令用来系统关机命令.shutdown指令可以关闭所有程序,并依用户的需要,进行重新开机或关机的动作. 语法: shutdown(选项)(参数) 选项: -c:当执行“shutdown ...
- 收藏一个匹配html内容的文章
http://blog.csdn.net/donglynn/article/details/35788879