1、C语言中处理错误的方式:
①assert,当程序发生错误时终止程序,如内存错误等
②打印错误状态信息,perro、errno
③C标准库中的setjmp和longjmp的组合使用
首先设置一个跳转点(setjmp() 函数可以实现这一功能),然后在其后的代码中任意地方调用 longjmp() 跳转回这个跳转点上,以此来实现当发生异常时,转到处理异常的程序上,在其后的介绍中将介绍如何实现。
setjmp() 为跳转返回保存现场并为异常提供处理程序,longjmp() 则进行跳转(抛出异常),setjmp() 与 longjmp() 可以在函数间进行跳转,这就像一个全局的 goto 语句,可以跨函数跳转。
2、异常的概念:程序在运行过程中由于发生了某种村务而导致程序中途退出的情况称为异常
3、异常的用法
当程序发生异常时可以用throw进行抛出异常,异常抛出之后必须捕获(可以联想精神院病人发疯,如果不加以控制就会造成难以想象的后果)
当需要捕获异常时可以使用catch进行异常捕获,进而对异常做出相应处理
捕获异常之前必须先使用try进行异常判断
具体代码实现:
#include <iostream>
using namespace std;
int div(int& a, int& b) {
if(b == 0) {
throw 1;
}
return a / b;
}
int main()
{
int a,b;
cin >> a >> b;
try {
div(a,b);
}
catch(int err) {
cout << "错误码:" << err << endl;
}
return 0;
}
异常的抛出匹配原则:catch优先处理 与该对象类型匹配且举例最近的抛出异常;使用catch(…)可以捕获任意类型的异常。
栈展开:首先检查throw本身是否在try内部,如果在的话继续查找是否有匹配的catch语句,如果有的话就进行处理;否则的话退出当前函数,去下一个函数重复上述步骤 若到了main函数中也没匹配到,则程序会终止。
异常的重新抛出:
异常的安全问题:C++中可以使用RAII机制解决异常中的安全问题
①构造函数和析构函数中一般不建议抛出异常,容易导致对象创建不完整或资源释放不完整
②new和delete中抛出异常可能会导致内存泄漏
③多线程中可能由于抛出异常导致死锁问题,
异常规范:就是规定什么时候该抛出异常,什么时候不该抛出异常
①Base() throw() ;在函数原型后加throw()表示此函数不抛出异常
②void new_style() noexcept; C++11中在函数原型后加上noexcept关键字也可以表示此函数不抛出异常
4、异常体系
4.1、C+++标准库异常体系
4.2、自定义异常体系:通过继承和重载 exception 类来定义新的异常
5、异常的优缺点
优点:方便调试bug;可以更好的进行白盒测试等
缺点:容易导致程序到处乱跳,增加分析程序困难性,如果不规范使用可能会随意抛出异常导致不可预估的后果总结:总之只要规范使用异常机制可以很好的爆竹我们提高调试程序的效率,从而使我们少掉头发