目录
C语言的异常处理方式
C++的异常处理方式
异常的抛出与捕获
抛出与捕获原则
异常安全
C语言的异常处理方式
1、终止程序
常见形式:assert
缺陷:太过强硬,如果发生内存错误,或者除0语法错误等就会直接终止程序
2、返回错误码
缺陷:需要程序员自己去查找对应的错误,如系统的很多库的接口函数都是通过把错误码放到errno中,表示错误
C语言中基本都是使用返回错误码的方式处理错误,部分情况下使用终止程序处理非常严重的错误
C++的异常处理方式
基本概念:抛异常是编程中的一种机制(c++ / python等),用于在程序遇到错误或异常情况时中断正常的程序流,并将控制权转移到预定的异常处理逻辑中。异常处理使得程序能够优雅地处理错误,而不是直接崩溃(异常是一种运行时错误,可以中断程序的正常流程,常见的异常包括除零错误、文件未找到、网络连接失败等)
- 抛出(Throwing): 使用
throw
关键字将异常对象传递出去 - 捕获(Catching): 使用
try...catch
块来捕获并处理异常
try{// 可能会出现异常的代码
}//根据类型抛出异常的类型进行捕获
catch( ExceptionName e1 ){//处理方式}
catch( ExceptionName e2 ){//处理方式}
....
- 传播(Propagation):如果异常未被捕获,它会向调用栈的上传递,直到找到一个处理器,如果找不到一个处理器就会使程序终止
- 异常对象:该对象包含了错误的详细信息以及上下文,用于捕获和处理异常
优点:
- 提高代码的健壮性,使得程序能够优雅地处理异常情况
- 提供了错误传播和处理的标准机制
缺点:
- 可能会使代码变得复杂,其中的栈展开机制会打乱正常的执行流
- break、continue、return等虽然也会破坏正常执行流,但并会跨越多个函数
- 不当的异常处理可能会掩盖程序中的逻辑错误
异常的抛出与捕获
抛出与捕获原则
#include<iostream>
using namespace std;double Division(int a, int b)
{// 当b == 0时抛出异常if (b == 0)throw "Division by zero condition!";elsereturn ((double)a / (double)b);//否则返回a / b后的结果
}void fxx()
{int i = 0;cin >> i;if (i % 2 == 0)//出现偶数时抛异常{throw 1;}
}void Func()
{int a, b;cin >> a >> b;cout << Division(a, b) << endl;try{fxx();//可能出异常的代码}catch (int x){cout <<__LINE__<<"捕获异常:" << x << endl;}cout << "=====================" << endl;}int main()
{try {Func();}catch (const char* errmsg){cout << errmsg << endl;}catch (int x){cout << __LINE__ <<"捕获异常:"<< x << endl;}cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;return 0;
}
1、抛出异常的对象的类型决定了会调用哪个catch中的异常处理代码
2、进行异常处理的代码应该是离抛异常位置最近的那一个(就近原则)
3、找到匹配的catch子句并处理后,会继续执行catch子句后的非try...catch块中的内容。不会执行原函数中的内容了
4、抛出异常对象后,会生成一个拷贝该异常对象得到的临时对象(右值),这个临时对象会在被catch后销毁,可以调用移动构造从而省去拷贝构造这一过程
void fxx()
{int i = 0;cin >> i;if (i % 2 == 0){string s("出现偶数");throw s;}
}
5、catch(...)可以捕获任意类型的异常对象,用于捕获未知异常对象的情况,是异常捕获的最后一道防线必须加上,防止出现在规定的异常对象外的情况而捕捉不到的情况
6、实际上,抛出对象的类型与捕获的类型并不一定都是匹配的,大多数情况下会抛出派生类对象,使用基类捕获
异常安全
1、最好不要在构造函数中抛出异常,否则可能导致对象不完整或者没有完全初始化
2、最好不要在析构函数中抛出异常,析构函数主要用于资源的清理,抛异常可能导致资源泄漏
3、在C++异常中经常会导致资源泄漏的问题,比如在new和delete中抛出了异常,导致内存泄漏,在lock和unlock之间抛出了异常导致死锁,C++经常使用RALL来解决上述问题
~over~