异常
通常的程序异常有两种:
- 编译异常:即语法错误。程序无法生成运行代码。
- 逻辑异常:包含可预料和不可预料两类。
C++提供了一些内置的语言特性来产生(raise)或抛出(throw)异常,用以通知“异常已经发生”,然后由预先安排的程序段来捕获(catch)异常,并对其进行处理。这种机制可以使连那个无关(往往是独立开发)的部分进行“异常”通信。由程序的某一部分引发了另一部分的异常,这一异常可沿着程序函数的调用链回到引起异常的部分去处理,这也能很好的分清责任。
异常处理
- 在小型程序中,一旦发生错误,一般是将程序立即中断运行,从而无条件释放所有资源。
- 在大型程序中,运行中一旦发生异常,应该允许恢复和继续运行。恢复的过程就是把产生异常所造成的恶劣影响去掉,中间可能要涉及一系列的函数调用链的退栈,对象的析构,资源的释放等。继续运行就是异常处理之后,在紧接着异常处理的代码区域中继续运行。
异常的基本思想:
- 实际的资源分配(如内存申请或文件打开)通常在程序的底层进行。
- 当操作失败、无法分配内存或无法打开一个文件时,在逻辑上如何进行处理通常是在程序的高层,中间可能还有与用户的对话。
- 异常为从分配资源的代码转向处理错误状态的代码提供了一种表达方式,如果还存在中间层次的函数,则为它们释放所分配的内存提供了机会,但是并不包括用于传递错误状态信息的代码。
异常处理的目的:
在异常发生时,尽可能地减小破坏,周密地善后,而不去影响其他部分程序的运行。
异常处理的步骤:
- 定义异常(try语句块)将那些可能产生错误的语句框定在try块中;
- 定义异常处理(catch语句块)将异常处理的语句放在catch中,以便异常被传递过来时就处理它;
- 抛掷异常(throw语句)检测是否产生异常,若是,则抛掷异常。
try--catch的一般语法如下:
try
{
//try 语句块
}
catch(类型1 参数1)
{
//针对类型1的异常处理
}
catch(类型2 参数2)
{
//针对类型2的异常处理
}
......
catch(类型n 参数n)
{
//针对类型n的异常处理
}
例如:定义除0异常
// divisionZeroAbnormal.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
double Div(double a, double b)
{
if(b == 0.0)
throw b;
return a/b;
}
int main()
{
try
{
cout<<"7.3/2.0="<<Div(7.3,2.0)<<endl;
cout<<"7.3/0.0="<<Div(7.3,0.0)<<endl;
cout<<"7.3/1.0="<<Div(7.3,1.0)<<endl;
}
catch(double)
{
cout<<"exception of dividing zero.\n";
}
cout<<"That is ok.\n";
return 0;
}
结果
7.3/2.0=3.65
exception of dividing zero.
That is ok.
请按任意键继续. . .
catch()处理程序的出现顺序很重要,因为在一个try块中,异常处理程序是按着它出现的顺序被检查的。只要找到一个匹配的异常类型,后面的异常处理都被忽略掉。
catch(...)是一个特殊的捕获语句,可以捕获任何异常,因而如果其他catch语句未捕获到异常,可将catch(...)放在最后来捕获,如果不在最后,会产生编译错误。
// Ch7_2.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
using namespace std;
void f(int n)
{
try
{
if(n == 0) throw n;
if(n == 1) throw 'a';
if(n == 2) throw 12.45;
}
catch(int intE)
{
cout<<"捕捉整形数据类型:"<<intE<<endl;
}
/*catch(char charE)
{
cout<<"捕捉整形数据类型:"<<charE<<endl;
}*/
catch(double doubleE)
{
cout<<"捕捉整形数据类型:"<<doubleE<<endl;
}
catch(...)
{
cout<<"默认捕获,可捕获所有类型"<<endl;
}
return;
}
int main()
{
f(0);
f(1);
f(2);
return 0;
}
结果
捕捉整形数据类型:0
默认捕获,可捕获所有类型
捕捉整形数据类型:12.45
请按任意键继续. . .