当前位置:   article > 正文

70-异常处理深度解析_terminate called after throwing an instance of 'in

terminate called after throwing an instance of 'int

注:博客中内容主要来自《狄泰软件学院》,博客仅当私人笔记使用。

测试环境:Ubuntu 10.10

GCC版本:9.2.0

 

一、异常处理深度解析

1)问题

                如果在main函数中抛出异常会发生什么?

 

2)如果异常不处理,最后会传到哪里

3)下面的代码输出什么?

 

  1. 编程实验
  2. 异常的最终处理?
  3. E1-1.cpp
  4. #include <iostream>
  5. using namespace std;
  6. class Test
  7. {
  8. public:
  9. Test()
  10. {
  11. cout << "Test()";
  12. cout << endl;
  13. }
  14. ~Test()
  15. {
  16. cout << "~Test()";
  17. cout << endl;
  18. }
  19. };
  20. int main()
  21. {
  22. static Test t;
  23. throw 1;
  24. return 0;
  25. }

操作:g++编译,编译正常。打印结果:
 

  1. Test()
  2. terminate called after throwing an instance of 'int' 
  3. Aborted(core dumped)

 

4)如果异常无法被处理,terminate()结束函数会被自动调用

5)默认情况下,terminate()调用库函数abort()终止程序。

6)abort()函数使得程序执行异常而立即退出

7)C++支持替换默认的terminate()函数实现

8)terminate()函数的替换

    -    自定义一个无返回值无参数的函数

           *不能抛出任何异常

           *必须以某种方式结束当前程序

    -    调用set_terminate()设置自定义的结束函数

           *参数类型为void(*)()

           *返回值为默认的terminate()函数入口地址

  1. 编程实验
  2. 自定义结束函数
  3. E1-2.cpp
  4. #include <iostream>
  5. #include <cstdlib>
  6. #include <exception>    //异常处理相关东西
  7. using namespace std;
  8. void my_terminate()
  9. {
  10. cout << "void my_terminate()" << endl;
  11. //exit(1);    //确保全局对象和静态局部对象都正常析构
  12. abort();
  13. }
  14. class Test
  15. {
  16. public:
  17. Test()
  18. {
  19. cout << "Test()";
  20. cout << endl;
  21. }
  22. ~Test()
  23. {
  24. cout << "~Test()";
  25. cout << endl;
  26. }
  27. };
  28. int main()
  29. {
  30. set_terminate(my_terminate);
  31. static Test t;
  32. throw 1;
  33. return 0;
  34. }

操作:

1)g++编译(使用exit),编译正常。打印结果:

  1. Test()
  2. void my_terminate()
  3. ~Test() //来自static Test t的析构函数

2)g++编译(使用abort),编译正常。打印结果:

  1. Test()
  2. void my_terminate()

两个重要知识点
1、main函数里的异常,如果没有没处理,会被一个全局的函数给处理掉。
2、C++编译器之间存在差异(对异常处理已经证明)

 

面试题

            如果析构函数中抛出异常会发生什么情况?

1、析构函数是释放资源的地方,如果抛出异常,导致资源不能正确释放。

2、导致全局结束函数terminate()重复调用,使系统进入不稳定状态。

  1. 编程实验
  2. 析构函数抛出异常
  3. E1-3.cpp
  4. #include <iostream>
  5. #include <cstdlib>
  6. #include <exception>
  7. using namespace std;
  8. void my_terminate()
  9. {
  10. cout << "void my_terminate()" << endl;
  11. // exit(1);
  12. abort();
  13. }
  14. class Test
  15. {
  16. public:
  17. Test()
  18. {
  19. cout << "Test()";
  20. cout << endl;
  21. }
  22. ~Test()
  23. {
  24. cout << "~Test()";
  25. cout << endl;
  26. throw 2;
  27. }
  28. };
  29. int main()
  30. {
  31. set_terminate(my_terminate);
  32. static Test t;
  33. throw 1;
  34. return 0;
  35. }

操作:

1)g++编译正常,打印结果:
 

  1. Test()
  2. void my_terminate()    //解决throw 1
  3. ~Test()                //解决throw 1异常时,触发exit(1),然后调用析构函数
  4. void my_terminate()    //抛出异常throw 2,再次触发异常处理函数,打印这个结果

之所以默认调用abort()函数,为了强制终止程序,防止调用析构函数时再次释放资源

 

小结

1)如果异常没有被处理,最后terminate()结束整个程序

2)terminate()是整个程序释放系统资源的最后机会

3)结束函数可以自定义,但不能继续抛出异常

4)析构函数中不能抛出异常,可能导致terminate()多次调用

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/939548
推荐阅读
相关标签
  

闽ICP备14008679号