1.异常的最终处理
(1)问题:如果在main函数中抛出异常会发生什么?如果异常不处理,最后会传到哪里?
(2)下面的代码的输出什么?
编程实验:异常的最终处理?
#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; }
运行结果:不同编译器的运行结果不同
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
Test()
terminate called after throwing an instance of 'int'
Aborted (core dumped)
2.结束函数terminate()
(1)结束函数terminate():
-
如果异常无法被处理,terminate() 结束函数会被自动调用
-
默认情况下,terminate() 调用库函数 abort() 终止程序
-
abort() 函数使得程序执行异常而立即退出
-
C++支持替换默认的 terminate() 函数实现
(2)terminate() 函数的替换:
-
自定义一个无返回值无参数的函数
-
不能抛出任何异常
-
必须以某种方式结束当前程序
-
-
调用 set_terminate() 设置自定义的结束函数
-
参数类型为
void (*) ()
-
返回值为默认的 terminate() 函数入口地址
-
编程实验:自定义结束函数
#include <iostream> #include <cstdlib> #include <exception> using namespace std; void my_terminate() { cout << "void my_terminate()" << endl; exit(1); } 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; }
运行结果:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
Test()
void my_terminate()
~Test()
将exit(1);
改为abort();
后的运行结果:
示例2:自定义结束函数
void my_terminate() { cout << "void my_terminate()" << endl; // exit(1); abort(); }
运行结果:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
Test()
void my_terminate()
Aborted (core dumped)
(abort()函数是异常终止一个程序,并且异常终止的时候不会调用任何对象的析构函数。如果调用的是exit()函数,那么会确保所有的全局对象和静态局部对象的析构函数被调用)
3.面试题:如果析构函数中抛出异常会发生什么情况?
示例:析构函数抛出异常
#include <iostream> #include <cstdlib> #include <exception> using namespace std; void my_terminate() { cout << "void my_terminate()" << endl; exit(1); } 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; }
运行结果:
[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
Test()
void my_terminate()
~Test()
Aborted (core dumped)
(析构函数中不能抛出异常,可能导致 terminate() 多次调用)
(不同编译器之间在默认的terminate() 函数实现上有差异)
4.小结
-
如果异常没有被处理,最后 terminate() 结束整个程序
-
terminate() 是整个程序释放系统资源的最后机会
-
结束函数可以自定义,但不能继续抛出异常
-
析构函数中不能抛出异常,可能导致 terminate() 多次调用