C++异常处理

C++异常处理方式


1 . 终止程序(除数为0)
2 . 返回一个表示错误的值,附加错误码(GetLastError())
3 . 返回一个合法值,让程序处于某种非法的状态(坑爹的atoi())
4 . 调用一个预先准备好在出现”错误”的情况下用的函数(回调函数)
5 . 暴力解决方式:abort()或者exit()
6 . 使用goto语句
7 . setjmp()和longjmp()组合 (setjump必须先调用,在异常位置通过调用longjmp以恢复先前被保存的程序执行点,否则将导致不可预测的结果,甚至程序崩溃在调用setjmp的函数返回之前调动longjmp,否则结果不可预料)


常见异常处理


异常,当一个函数发现自己无法处理的错误时抛出异常,让函数的调用者直接或间接的处理这个问题


异常的抛出和捕获

1 . 异常是通过抛出对象而引发的,该对象的类型决定了应该激活哪个处理代码
2 . 被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的那一个
3 . 抛出异常后会释放局部存储对象,所以被抛出的对象也就还给系统了,throw表达式会初始化一个抛出特殊的异常对象副本(匿名对象),异常对象由编译管理,异常对象在传给对应的catch处理之后撤销


.栈展开

抛出异常的时候,将暂停当前函数的执行,开始查找对应的匹配catch子句。首先检查throw本身是否在try块内部,如果是再查找匹配的catch语句。如果有匹配的,则处理。没有则退出当前函数栈,继续在调用函数的栈中进行查找,不断重复上述过程,若到达main函数的栈,依旧没有匹配的,则终止程序。上述这个沿着调用链查找匹配的catch子句的过程称为栈展开。找到匹配的catch子句并处理以后,会继续沿着catch子句后面继续执行


这里写图片描述


异常捕获的匹配规则

异常对象的类型与catch说明符的类型必须完全匹配。只有以下几种情况例外:
1 . 允许从非const对象到const的转换
2 . 允许从派生类型到基类类型的转换
3 . 将数组转换为指向数组类型的指针,将函数转换为指向函数类型的指针


这里写图片描述


异常重新抛出

有可能单个的catch不能完全处理一个异常,在进行一些校正处理以后,希望再交给更外层的调用链函数来处理,catch则可以通过重新抛出将异常传递给更上层的函数进行处理


异常规范
(C++已经省去掉)

//异常规范


int Div(int child,int parent)throw(int){
//表示该函数抛异常只能抛出整型
    if(0 == parent)
        throw 0;
    return child/parent;
}

注意:最好不要在构造函数和析构函数中抛异常


1 . 构造函数完成对象的构造和初始化,需要保证不要在构造函数中抛出异常,否则可能导致对象不完整或没有完全初始化
2 . 析构函数主要完成资源的清理,需要保证不要在析构函数内抛出异常,否则可能导致资源泄漏(内存泄漏、句柄未关闭等)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值