异常处理
异常处理对于编写健壮的软件来说无疑是非常重要的,是否有完善的异常处理机制也是评价某一程序设计语言优劣的一个重要标准。
总的来说,对于小型程序和大型程序出现异常时,其处理的思想和方法稍有差别。一般来说,当小型程序在出现异常时,则将程序立即中断运行,无条件释放所有资源;对于大型程序,则沿着函数等调用的逻辑关系,逆向回溯报告错误。
基本思想是:在底层(执行层)发现的问题,逐级上报,直到有能力可以处理异常的那一级为止。如果程序最终没有相应的代码来处理该异常,那么操作系统就会简单粗暴地shut down该程序,或者死机。
异常处理的实现
记得要#include <fstream>
哦~
使用 try / catch 捕获异常
基本格式长这样…
try
{
Test(); // 可能产生错误的语句
}
catch(int /* 异常类型声明1 */)
{
/* 异常处理语句块1 */
}
catch(char /* 异常类型声明2 */)
{
/* 异常处理语句块2 */
}
catch(long /* 异常类型声明3 */)
{
/* 异常处理语句块3 */
}
catch(...)
{
cout<<"未知异常"<<endl;
}
注意:
- 被检测部分必须放在try块中,否则不起作用
- try块和catch块是一个整体,catch块必须紧跟在try块之后
- 一个try-catch结构中只有一个try块,但可有多个catch块
- catch后面的圆括号中,一般只写异常信息的类型;catch(int)
- 不知道异常信息的类型,用catch(…)接收
- try-catch结构和throw可以在同一函数中,也可以不在
so这个try / catch有一些像switch / case语句诶有木有…
使用throw抛出异常
如果在try语句块的程序段中(包括在其中调用的函数)发现了异常,且抛出了该异常,则这个异常就可以被try语句后面的某个catch所捕获并处理,条件是被抛出的类型与catch语句的异常类型相匹配。由于C++使用数据类型来区分不同的异常,故throw中表达式的值就没有实际意义,而表达式的类型就十分重要啦
来一段示例
#include <fstream>
#include <iostream>
using namespace std;
double Div(double a, double b) // 自定义带有错误反馈的函数
{
if (b-0.0 < 1e-7)
{
throw b; // 抛出异常
}
return a / b;
}
int main(int argc, char const *argv[])
{
try // 定义异常
{
cout << "7.3/2.0 =" << ends << Div(7.3, 2.0) << endl;
cout << "7.3/0.0 =" << ends << Div(7.3, 0.0) << endl; // 出现异常
cout << "7.3/1.0 =" << ends << Div(7.3, 1.0) << endl;
}
catch(double) // 定义异常处理
{
cout << "exception of dividing zero!" << endl;
}
cout << "that's okay" << endl;
return 0;
}
运行结果(vscode,MacOS)
所以…这东西到底强到哪了呢