问题:
如果在main函数中抛出异常会发生什么?
上述实验结果:
bcc结果:
vs2010结果:
linux结果:
自定义结束函数:
1 #include <iostream> 2 #include <cstdlib> 3 #include <exception> 4 5 using namespace std; 6 7 void my_terminate() 8 { 9 cout << "void my_terminate()" << endl; 10 exit(1); 11 } 12 13 class Test 14 { 15 public: 16 Test() 17 { 18 cout << "Test()"; 19 cout << endl; 20 } 21 22 ~Test() 23 { 24 cout << "~Test()"; 25 cout << endl; 26 } 27 }; 28 29 30 int main() 31 { 32 set_terminate(my_terminate); 33 34 static Test t; 35 36 throw 1; 37 38 return 0; 39 }
结果如下:
第10行的exit(1)保证所有的全局对象和局部静态对象都正常的析构。
将第10行的exit换成abort,则结果如下:
可以看到换成abort之后,不会调用析构函数。
将程序改回exit(1),去window下去实验。
bcc的结果如下:
vs2010结果:
可以看到,这三款编译器的行为变得一致了。
问题:
如果析构函数中抛出异常会发生什么?
示例程序:
1 #include <iostream> 2 #include <cstdlib> 3 #include <exception> 4 5 using namespace std; 6 7 void my_terminate() 8 { 9 cout << "void my_terminate()" << endl; 10 exit(1); 11 } 12 13 class Test 14 { 15 public: 16 Test() 17 { 18 cout << "Test()"; 19 cout << endl; 20 } 21 22 ~Test() 23 { 24 cout << "~Test()"; 25 cout << endl; 26 27 throw 2; 28 } 29 }; 30 31 32 int main() 33 { 34 set_terminate(my_terminate); 35 36 static Test t; 37 38 throw 1; 39 40 return 0; 41 }
exit(1)被调用到的时候,再次出发对象的析构函数,在析构函数中又一次抛出异常,导致自定义的结束函数又一次被调用。如果在结束函数中释放资源,就会造成多次释放,容易造成崩溃。
结果如下:
因此,我们将exit换成abort,这也是默认结束函数的行为,abort会直接结束程序。
实际编程时不要在析构函数中扔出异常。
小结: