赞
踩
注:博客中内容主要来自《狄泰软件学院》,博客仅当私人笔记使用。
测试环境:Ubuntu 10.10
GCC版本:9.2.0
一、异常处理深度解析
1)问题
如果在main函数中抛出异常会发生什么?
2)如果异常不处理,最后会传到哪里?
3)下面的代码输出什么?
- 编程实验
- 异常的最终处理?
- E1-1.cpp
- #include <iostream>
-
-
- using namespace std;
-
-
- class Test
- {
- public:
- Test()
- {
- cout << "Test()";
- cout << endl;
- }
-
-
- ~Test()
- {
- cout << "~Test()";
- cout << endl;
- }
- };
-
-
- int main()
- {
- static Test t;
-
-
- throw 1;
-
-
- return 0;
- }

操作:g++编译,编译正常。打印结果:
- Test()
- terminate called after throwing an instance of 'int'
- Aborted(core dumped)
4)如果异常无法被处理,terminate()结束函数会被自动调用
5)默认情况下,terminate()调用库函数abort()终止程序。
6)abort()函数使得程序执行异常而立即退出
7)C++支持替换默认的terminate()函数实现
8)terminate()函数的替换
- 自定义一个无返回值无参数的函数
*不能抛出任何异常
*必须以某种方式结束当前程序
- 调用set_terminate()设置自定义的结束函数
*参数类型为void(*)()
*返回值为默认的terminate()函数入口地址
- 编程实验
- 自定义结束函数
- E1-2.cpp
- #include <iostream>
- #include <cstdlib>
- #include <exception> //异常处理相关东西
-
-
- using namespace std;
-
-
- void my_terminate()
- {
- cout << "void my_terminate()" << endl;
- //exit(1); //确保全局对象和静态局部对象都正常析构
- abort();
- }
-
-
- class Test
- {
- public:
- Test()
- {
- cout << "Test()";
- cout << endl;
- }
-
- ~Test()
- {
- cout << "~Test()";
- cout << endl;
- }
- };
-
-
-
-
- int main()
- {
- set_terminate(my_terminate);
-
- static Test t;
-
- throw 1;
-
- return 0;
- }

操作:
1)g++编译(使用exit),编译正常。打印结果:
- Test()
- void my_terminate()
- ~Test() //来自static Test t的析构函数
2)g++编译(使用abort),编译正常。打印结果:
- Test()
- void my_terminate()
两个重要知识点
1、main函数里的异常,如果没有没处理,会被一个全局的函数给处理掉。
2、C++编译器之间存在差异(对异常处理已经证明)
面试题
如果析构函数中抛出异常会发生什么情况?
1、析构函数是释放资源的地方,如果抛出异常,导致资源不能正确释放。
2、导致全局结束函数terminate()重复调用,使系统进入不稳定状态。
- 编程实验
- 析构函数抛出异常
- E1-3.cpp
- #include <iostream>
- #include <cstdlib>
- #include <exception>
-
-
- using namespace std;
-
-
- void my_terminate()
- {
- cout << "void my_terminate()" << endl;
- // exit(1);
- abort();
- }
-
-
- class Test
- {
- public:
- Test()
- {
- cout << "Test()";
- cout << endl;
- }
-
- ~Test()
- {
- cout << "~Test()";
- cout << endl;
-
- throw 2;
- }
- };
-
-
-
-
- int main()
- {
- set_terminate(my_terminate);
-
- static Test t;
-
- throw 1;
-
- return 0;
- }

操作:
1)g++编译正常,打印结果:
- Test()
- void my_terminate() //解决throw 1
- ~Test() //解决throw 1异常时,触发exit(1),然后调用析构函数
- void my_terminate() //抛出异常throw 2,再次触发异常处理函数,打印这个结果
之所以默认调用abort()函数,为了强制终止程序,防止调用析构函数时再次释放资源
小结
1)如果异常没有被处理,最后terminate()结束整个程序
2)terminate()是整个程序释放系统资源的最后机会
3)结束函数可以自定义,但不能继续抛出异常
4)析构函数中不能抛出异常,可能导致terminate()多次调用
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。