为了能够编写适当的catch子句,了解一个函数是否抛出异常或会抛出哪些异常对函数的用户来说是很有帮助的。
而我们可以通过 异常说明 进行对一个函数的异常进行说明, 如果函数抛出异常,被抛出的异常将是包含在该说明中的一种或是从列出的异常中派生的类型。
异常说明有如下的几种形式:
1. 指定异常
T funNname( parameterlist ) throw( T1, T2,····,Tn);
其中 T 是类型, parameterlist 是参数列表, 而类型 T1, T2,····,Tn 是函数会抛出的异常。
2. 不抛出异常
T funNname( parameterlist ) throw( );
抛出异常类型列表为空,表示的是该函数不抛出任何类型异常。
3. 抛出任意类型的异常
T funNname( parameterlist );
这表示该函数可以抛出任意类型的异常。
下面通过一段简单的代码来说明异常说明的特别之处
#include <iostream>
class demo
{
};
using namespace std;
double divd(int a, int b) throw(int) //异常说明,表示函数divd会抛出类型为int的异常
{
if(b == 0) throw demo(); //抛出类型为demo的异常
return a/b;
}
int main()
{
try
{
divd(1,0);
}
catch(demo) //捕获异常类型demo
{
cout << " divided by zero " << endl;
}
catch(int) //捕获异常类型int
{
cout<<"zero"<<endl;
}
return 0;
}
这段代码的运行结果是输出:
divided by zero
奇怪了,在 divd 函数的声明中,只说明了抛出类型为 int 的异常,为什么其函数内抛出的异常类型却为demo呢?
我们可以暂时理解为:在某函数的异常说明中的列出的类型与该函数内抛出的异常类型不完全匹配时, 但在异常处理代码中的catch有对其类型的捕获, 所以程序运行正常。
好,下面我们根据异常说明进行一些修改
double divd(int a, int b) throw( ) //将throw(int) 改为 throw( )
修改之后,编译运行,看到的输出结果还是:
divided by zero
根据上面对异常说明的三种形式介绍,我们知道在函数声明后面添加 throw()的意思是说明了此函数不会抛出任何的异常。那为什么这里抛出了而且又被捕获呢?
其实,在编译的时候,编译器不能也不会试图验证异常说明。因不能在编译时检查异常说明,异常说明的应用通常是有限的!