0.目录

1.异常的最终处理

2.结束函数terminate()

3.小结

1.异常的最终处理

问题:

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

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

下面的代码的输出什么?

示例——异常的最终处理?:

  1. #include <iostream>
  2. using namespace std;
  3. class Test
  4. {
  5. public:
  6. Test()
  7. {
  8. cout << "Test()";
  9. cout << endl;
  10. }
  11. ~Test()
  12. {
  13. cout << "~Test()";
  14. cout << endl;
  15. }
  16. };
  17. int main()
  18. {
  19. static Test t;
  20. throw 1;
  21. return 0;
  22. }

运行结果为:

  1. [root@bogon Desktop]# g++ test.cpp
  2. [root@bogon Desktop]# ./a.out
  3. Test()
  4. terminate called after throwing an instance of 'int'
  5. Aborted (core dumped)

(不同编译器的运行结果不同。)

2.结束函数terminate()

  • 如果异常无法被处理,terminate() 结束函数会被自动调用
  • 默认情况下,terminate() 调用库函数 abort() 终止程序
  • abort() 函数使得程序执行异常而立即退出
  • C++支持替换默认的 terminate() 函数实现

terminate() 函数的替换:

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

    1. 不能抛出任何异常
    2. 必须以某种方式结束当前程序
  • 调用 set_terminate() 设置自定义的结束函数
    1. 参数类型为 void (*) ()
    2. 返回值为默认的 terminate() 函数入口地址

示例1——自定义结束函数:

  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <exception>
  4. using namespace std;
  5. void my_terminate()
  6. {
  7. cout << "void my_terminate()" << endl;
  8. exit(1);
  9. }
  10. class Test
  11. {
  12. public:
  13. Test()
  14. {
  15. cout << "Test()";
  16. cout << endl;
  17. }
  18. ~Test()
  19. {
  20. cout << "~Test()";
  21. cout << endl;
  22. }
  23. };
  24. int main()
  25. {
  26. set_terminate(my_terminate);
  27. static Test t;
  28. throw 1;
  29. return 0;
  30. }

运行结果为:

  1. [root@bogon Desktop]# g++ test.cpp
  2. [root@bogon Desktop]# ./a.out
  3. Test()
  4. void my_terminate()
  5. ~Test()

exit(1);改为abort();后的运行结果:

示例2——自定义结束函数:

  1. void my_terminate()
  2. {
  3. cout << "void my_terminate()" << endl;
  4. // exit(1);
  5. abort();
  6. }

运行结果为:

  1. [root@bogon Desktop]# g++ test.cpp
  2. [root@bogon Desktop]# ./a.out
  3. Test()
  4. void my_terminate()
  5. Aborted (core dumped)

(abort()函数是异常终止一个程序,并且异常终止的时候不会调用任何对象的析构函数。如果调用的是exit()函数,那么会确保所有的全局对象和静态局部对象的析构函数被调用。)

面试题:

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

示例——析构函数抛出异常:

  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <exception>
  4. using namespace std;
  5. void my_terminate()
  6. {
  7. cout << "void my_terminate()" << endl;
  8. exit(1);
  9. }
  10. class Test
  11. {
  12. public:
  13. Test()
  14. {
  15. cout << "Test()";
  16. cout << endl;
  17. }
  18. ~Test()
  19. {
  20. cout << "~Test()";
  21. cout << endl;
  22. throw 2;
  23. }
  24. };
  25. int main()
  26. {
  27. set_terminate(my_terminate);
  28. static Test t;
  29. throw 1;
  30. return 0;
  31. }

运行结果为:

  1. [root@bogon Desktop]# g++ test.cpp
  2. [root@bogon Desktop]# ./a.out
  3. Test()
  4. void my_terminate()
  5. ~Test()
  6. Aborted (core dumped)

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

(不同编译器之间在默认的 terminate() 函数实现上有差异。)

3.小结

  • 如果异常没有被处理,最后 terminate() 结束整个程序
  • terminate() 是整个程序释放系统资源的最后机会
  • 结束函数可以自定义,但不能继续抛出异常
  • 析构函数中不能抛出异常,可能导致 terminate() 多次调用

C++解析-外传篇(1):异常处理深度解析的更多相关文章

  1. C++解析-外传篇(2):函数的异常规格说明

    0.目录 1.异常规格说明 2.unexpected() 函数 3.小结 1.异常规格说明 问题: 如何判断一个函数是否会抛出异常,以及抛出哪些异常? C++提供语法用于声明函数所抛出的异常 异常声明 ...

  2. C++解析-外传篇(3):动态内存申请的结果

    0.目录 1.动态内存申请一定成功吗? 2.new_handler() 函数 3.小结 1.动态内存申请一定成功吗? 问题: 动态内存申请一定成功吗? 常见的动态内存分配代码: C代码: C++代码: ...

  3. Java-XML解析第一篇主流开源类库解析XML

    1.流行的XML解析框架 1>底层解析方式:存在编码复杂性.难扩展.难复用.....想了解底层解析方式请参考:浅谈 Java XML 底层解析方式 2>Dom4j:基于 JAXP 解析方式 ...

  4. [WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析

    [WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析 标签: webkit内核JavaScriptCore 2015-03-26 23:26 2285 ...

  5. Unity加载模块深度解析(网格篇)

    在上一篇 加载模块深度解析(一)中,我们重点讨论了纹理资源的加载性能.这次,我们再来为你揭开其他主流资源的加载效率. 这是侑虎科技第53篇原创文章,欢迎转发分享,未经作者授权请勿转载.同时如果您有任何 ...

  6. 深入了解webkit内核第一篇:JavaScript引擎深度解析

    看到HorkeyChen写的文章<[WebKit] JavaScriptCore解析--基础篇(三)从脚本代码到JIT编译的代码实现>,写的很好,深受启发.想补充一些Horkey没有写到的 ...

  7. [WebKit内核] JavaScriptCore深度解析--基础篇(一)字节码生成及语法树的构建

    看到HorkeyChen写的文章<[WebKit] JavaScriptCore解析--基础篇(三)从脚本代码到JIT编译的代码实现>,写的很好,深受启发.想补充一些Horkey没有写到的 ...

  8. jQuery2.x源码解析(回调篇)

    jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 通过艾伦的博客,我们能看出,jQuery的pro ...

  9. Deep Learning模型之:CNN卷积神经网络(一)深度解析CNN

    http://m.blog.csdn.net/blog/wu010555688/24487301 本文整理了网上几位大牛的博客,详细地讲解了CNN的基础结构与核心思想,欢迎交流. [1]Deep le ...

随机推荐

  1. Python中的对象引用、浅拷贝与深拷贝

    最近项目中遇到一个Python浅拷贝机制引起的bug,由于对于Python中对象引用.赋值.浅拷贝/深拷贝机制没有足够的认识,导致调试了很久才发现问题,这里简单记录一下相关概念. 在Python的设计 ...

  2. [BZOJ1565][NOI2009]植物大战僵尸-[网络流-最小割+最大点权闭合子图+拓扑排序]

    Description 传送门 Solution em本题知识点是用网络流求最大点权闭合子图. 闭合图定义:图中任何一个点u,若有边u->v,则v必定也在图中. 建图:运用最小割思想,将S向点权 ...

  3. MYSQL中日期与字符串间的相互转换

    一.字符串转日期 下面将讲述如何在MYSQL中把一个字符串转换成日期: 背景:rq字段信息为:20100901 1.无需转换的: SELECT * FROM tairlist_day WHERE rq ...

  4. Tp框架之命名空间

    命名空间,相当于虚拟目录 实现自动加载类的机制 初始命名空间:Library文件夹 初始命名空间下面有很多根命名空间: 1.Library里面的文件夹 2.APP的模块文件夹 在tp框架中,只有这两个 ...

  5. linux安装PHP-memcache-redis扩展

    1.php memcache 扩展 http://pecl.php.net/package/memcache/3.0.8 下载文件源码 #tar zxvf memcache-3.0.8.tar#/us ...

  6. Jmeter接口测试(九)授权

    下面应该是jmeter的授权设置,但是由于本人目前对这块了解还不深,暂时写个标题,以后有时间再来补充,大家可以先看下一篇内容

  7. Lua学习笔记(6): 函数

    Lua的函数 函数用于简化程序,当某些工作需要重复执行的时候就可以使用函数减轻工作量(虽然复制粘贴也行) 语法: function 函数名(参数列表) 函数体 return 返回值 end --结束标 ...

  8. zepto 添加 animate组件

    今天发现JQuery可以用 animate方法回到顶部,心想着zepto应该也可以 $('html,body').animate({ scrollTop: 0 }, 1000); 于是便用了一下,发现 ...

  9. 【shell 每日一练7】一键安装mysql5.7,以及密码及策略修改

    一.一键安装Mysql脚本 [root@uat01 ~]# cat InstallMysql01.sh #!/bin/bash #-- #旅行者-Travel #.安装wget yum -y inst ...

  10. Composer指南

    安装 windows中安装Composer 一般来说,windows下安装composer有两种办法,一种是直接下载并运行Composer-Setup.exe,这种方法在中国似乎很难完成安装.另一种就 ...