异常的概念
程序在运行过程中可能产生异常
异常与bug对比:
-异常是程序运行时可预料的执行分支。
例:
运行时产生除0的情况
需要打开的外部文件不存在
数组访问时越界。
-bug是程序中的错误,是不被预期的运行方式
例:
使用野指针
堆数组使用结束后未释放
选择排序无法处理长度为0的数组
C语言经典处理方式:if…else…
void func(...)
{
if( 判断是否产生异常 )
{
正常情况代码逻辑;
}
else
{
异常情况代码逻辑;
}
}
注意:c语言中的经典异常处理方式会使得程序逻辑中混入大量的处理异常的代码。
正常逻辑代码和异常处理代码混合在一起,导致代码迅速膨胀,难以维护。。。
C++异常处理
C++中内置了异常处理的语法元素try…catch…
-try语句处理正常代码逻辑,catch语句处理异常情况,try语句中的异常由对应的catch语句处理
例:
try
{
double r = divide(1, 0);
}
catch(...)
{
cout << "Divide by zero..." << endl;
}
C++通过throw 语句抛出异常信息
例:
double divide(double a, double b)
{
const double delta = 0.0000000000000001;
double ret = 0;
if( !( (-delta < b) && (b < delta ) ) )
{
ret = a / b;
}
else
{
throw 0; //产生除0异常
}
return ret;
}
C++异常处理分析:
throw抛出的异常必须被catch处理,如果当前函数能够处理异常,那么程序继续往下执行,
如果当前函数无法处理异常,则函数停止执行,并返回。返回到哪里?未被处理的异常会
顺着函数调用栈向上传播,直到被处理为止,否则程序将停止执行。
同一个try语句可以跟上多个catch语句
catch语句可以定义具体函数处理的异常类型,不同类型的异常由不同的catch语句负责处理,
try语句中可以抛出任何类型的异常,catch(...)用于所有类型的异常,任何异常都只能被捕获
(catch)一次。
异常处理的匹配规则:
异常抛出后至上而下 严格匹配 每一个catch语句处理的类型。
例:
try
{
throw 1;
}
catch(type1 t1)
{
}
catch(type1 t2)
{
}
catch(typeN tn)
{
}
异常处理匹配时,不进行任何的类型转换。也就是严格匹配!
catch语句中可以抛出异常
catch中抛出的异常需要外层的try...catch...捕获
try
{
func();
}
catch(int i)
{
throw i;
}
catch(...)
{
throw; //将捕获的异常重新抛出
}
C++中的异常处理
异常的类型可以是自定义类类型,对于类类型异常的匹配依旧是至上而下严格匹配,赋值兼容性原则在异常
匹配中依然适用,一般而言:匹配子类异常的catch放在上部,匹配父类异常的catch放在下部。
在工程中会定义一系列的异常类,每个类代表工程中可能出现的一种异常类型,代码复用时,可能需要
重解释不同的异常类,在定义catch语句块时推荐使用引用作为参数。
C++标准库提供了实用异常类族,标准库中的异常都是从exception类派生的,exception类有两个主要的
分支,分别是:1,logic_errror,常用程序中的可以避免逻辑错误;2,runtime_error,常用于程序中无法
避免的恶性错误。
总结:后续更新。。。