外传篇2 函数的异常规格说明
1.异常规格说明
(1)问题:如何判断一个函数是否会抛出异常,以及抛出哪些异常?
(2)异常规格说明
-
C++提供语法用于声明函数所抛出的异常
-
异常声明作为函数声明的修饰符,写在参数列表后面
(3)异常规格说明的意义:
-
提示函数的调用者必须做好异常处理的准备
-
提示函数的维护者不要抛出其它异常
-
异常规格说明是函数接口的一部分
(4)问题:如果抛出的异常不在声明列表中,会发生什么?
下面的代码的输出什么?
编程实验:异常规格之外的异常
#include <iostream> using namespace std; void func() throw(int) { cout << "func()"; cout << endl; throw 'c'; } int main() { try { func(); } catch(int) { cout << "catch(int)"; cout << endl; } catch(char) { cout << "catch(char)"; cout << endl; } return 0; }
运行结果:不同编译器运行结果不一样
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
func()
terminate called after throwing an instance of 'char'
Aborted (core dumped)
2.unexpected() 函数
(1)unexpected() 函数
-
函数抛出的异常不在规格说明中,全局 unexpected() 被调用
-
默认的 unexpected() 函数会调用全局的 terminate() 函数
-
可以自定义函数替换默认的 unexpected() 函数实现
-
注意:不是所有的C++编译器都支持这个标准行为
(2)unexpected() 函数的替换
-
自定义一个无返回值无参数的函数
- 能够再次抛出异常
-
当异常符合触发函数的异常规格说明时,恢复程序执行
-
否则,调用全局 terminate() 函数结束程序
-
- 能够再次抛出异常
-
调用 set_unexpected () 设置自定义的异常函数
-
参数类型为
void (*) ()
-
返回值为默认的 unexpected() 函数入口地址
-
编程实验:自定义 unexpected() 函数
#include <iostream> #include <cstdlib> #include <exception> using namespace std; void my_unexpected() { cout << "void my_unexpected()" << endl; exit(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; }
运行结果:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
func()
void my_unexpected()
编程实验2: 自定义 unexpected() 函数
将exit();
改为throw 1;
后的运行结果
void my_unexpected() { cout << "void my_unexpected()" << endl; // exit(1); throw 1; }
运行结果:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
func()
void my_unexpected()
catch(int)
(程序恢复执行了)
(unexpected() 函数是正确处理异常的最后机会,如果没有抓住这次机会,全局的 terminate() 函数就会被调用,当前程序就只能以异常结束告终。)
3.小结
-
C++中的函数可以声明异常规格说明
-
异常规格说明可以看作接口的一部分
-
函数抛出的异常不在规格说明中,unexpected() 被调用
-
unexpected() 中能够再次抛出异常
-
异常能够匹配,恢复程序的执行
-
否则,调用 terminate() 结束程序
-
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步