问题:在实际工程开发中,我们通常会使用第三方库进行开发,而这时候我们是看不到源码的。
那么这时候,我们如何判断一个函数是否会抛出异常,以及抛出哪些异常?
C++提供了异常相关的语法
- C++提供语法用于声明函数所抛出的异常
- 异常声明作为函数声明的修饰符,卸载参数列表的后面
/* 可能抛出任何异常 */
void func1();
/* 只能抛出的异常类型:char和int */
void func2() throw(char, int);
/* 不抛出任何异常 */
void func3() throw();
异常规格说明的意义
- 提示函数调用者必须做好异常处理的准备
- 提示函数的维护者不要抛出其它异常
- 异常规格说明是函数接口的一部分
问题:如果抛出的异常不在声明列表中,会发生什么?
我们可以沿用在main函数抛出异常的方法来试验一下。看一下会发生什么情况。
当我们尝试抛出与声明列表不同的异常时,出现的现象跟在main()函数抛出异常的情况是相同的。那么我们可以说完全相同吗?
- 函数抛出的异常不在规格说明中,全局unexpected() 被调用
- 默认的unexpected() 函数会调用全局的 terminate() 函数
- 可以自定义函数替换默认的unexpected() 函数实现
- 注意:不是所有的C++编译器都支持这个标准行为。
unexpected() 函数的替换
自定义一个无返回值无参数的函数
能够再次抛出异常
当异常符合触发函数的异常规格说明时,恢复程序执行
否则,调用全局terminate() 函数结束程序调用set_unexpected() 设置自定义的异常函数
函数参数为void(*)()
返回值为默认的unexpected() 函数入口地址
示例代码:自定义unexpected() 函数
using namespace std;
void my_unexpected()
{
cout << "void my_unexpected()" << endl;
// exit(1);
throw 1;
}
void func() throw(int)
{
cout << "func()";
cout << endl;
throw 'c';
}
int main()
{
set_unexpected(my_unexpected);
try
{
func();
}
catch(int)
{
cout << "catch(int)";
cout << endl;
}
catch(char)
{
cout << "catch(char)";
cout << endl;
}
return 0;
}