C++解析-外传篇(1):异常处理深度解析
0.目录
1.异常的最终处理
2.结束函数terminate()
3.小结
1.异常的最终处理
问题:
如果在main函数中抛出异常会发生什么?
如果异常不处理,最后会传到哪里?
下面的代码的输出什么?
示例——异常的最终处理?:
#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()
- 如果异常无法被处理,terminate() 结束函数会被自动调用
- 默认情况下,terminate() 调用库函数 abort() 终止程序
- abort() 函数使得程序执行异常而立即退出
- C++支持替换默认的 terminate() 函数实现
terminate() 函数的替换:
- 自定义一个无返回值无参数的函数
- 不能抛出任何异常
- 必须以某种方式结束当前程序
- 调用 set_terminate() 设置自定义的结束函数
- 参数类型为
void (*) ()
- 返回值为默认的 terminate() 函数入口地址
- 参数类型为
示例1——自定义结束函数:
#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()函数,那么会确保所有的全局对象和静态局部对象的析构函数被调用。)
面试题:
如果析构函数中抛出异常会发生什么情况?
示例——析构函数抛出异常:
#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() 函数实现上有差异。)
3.小结
- 如果异常没有被处理,最后 terminate() 结束整个程序
- terminate() 是整个程序释放系统资源的最后机会
- 结束函数可以自定义,但不能继续抛出异常
- 析构函数中不能抛出异常,可能导致 terminate() 多次调用
C++解析-外传篇(1):异常处理深度解析的更多相关文章
- C++解析-外传篇(2):函数的异常规格说明
0.目录 1.异常规格说明 2.unexpected() 函数 3.小结 1.异常规格说明 问题: 如何判断一个函数是否会抛出异常,以及抛出哪些异常? C++提供语法用于声明函数所抛出的异常 异常声明 ...
- C++解析-外传篇(3):动态内存申请的结果
0.目录 1.动态内存申请一定成功吗? 2.new_handler() 函数 3.小结 1.动态内存申请一定成功吗? 问题: 动态内存申请一定成功吗? 常见的动态内存分配代码: C代码: C++代码: ...
- Java-XML解析第一篇主流开源类库解析XML
1.流行的XML解析框架 1>底层解析方式:存在编码复杂性.难扩展.难复用.....想了解底层解析方式请参考:浅谈 Java XML 底层解析方式 2>Dom4j:基于 JAXP 解析方式 ...
- [WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析
[WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析 标签: webkit内核JavaScriptCore 2015-03-26 23:26 2285 ...
- Unity加载模块深度解析(网格篇)
在上一篇 加载模块深度解析(一)中,我们重点讨论了纹理资源的加载性能.这次,我们再来为你揭开其他主流资源的加载效率. 这是侑虎科技第53篇原创文章,欢迎转发分享,未经作者授权请勿转载.同时如果您有任何 ...
- 深入了解webkit内核第一篇:JavaScript引擎深度解析
看到HorkeyChen写的文章<[WebKit] JavaScriptCore解析--基础篇(三)从脚本代码到JIT编译的代码实现>,写的很好,深受启发.想补充一些Horkey没有写到的 ...
- [WebKit内核] JavaScriptCore深度解析--基础篇(一)字节码生成及语法树的构建
看到HorkeyChen写的文章<[WebKit] JavaScriptCore解析--基础篇(三)从脚本代码到JIT编译的代码实现>,写的很好,深受启发.想补充一些Horkey没有写到的 ...
- jQuery2.x源码解析(回调篇)
jQuery2.x源码解析(构建篇) jQuery2.x源码解析(设计篇) jQuery2.x源码解析(回调篇) jQuery2.x源码解析(缓存篇) 通过艾伦的博客,我们能看出,jQuery的pro ...
- Deep Learning模型之:CNN卷积神经网络(一)深度解析CNN
http://m.blog.csdn.net/blog/wu010555688/24487301 本文整理了网上几位大牛的博客,详细地讲解了CNN的基础结构与核心思想,欢迎交流. [1]Deep le ...
随机推荐
- ARKit-1
1.1-AR技术简介 增强现实技术(Augmented Reality,简称 AR),是一种实时地计算摄影机影像的位置及角度并加上相应图像.视频.3D模型的技术,这种技术的目标是在屏幕上把虚拟世界套在 ...
- 【LG2183】[国家集训队]礼物
[LG2183][国家集训队]礼物 题面 洛谷 题解 插曲:不知道为什么,一看到这个题目,我就想到了这个人... 如果不是有\(exLucas\),这题就是\(sb\)题... 首先,若\(\sum_ ...
- ElasticSearch 聚合查询百分比
这里用的是es5.6.9 bucket_script :它执行一个脚本,该脚本可以对多桶聚合中的指定度量执行每桶计算,指定的度量标准必须为数字,并且脚本必须返回数值. 官方语法 https://www ...
- macOS 10.14 Mojave 开发环境配置Apache多PHP版本
第1部分:macOS 10.14 Mojave Web开发环境 在macOS上开发Web应用程序真是一种乐趣.设置开发环境有很多选择,包括广受欢迎的MAMP Pro,它在Apache,PHP和MySQ ...
- RestQL:现代化的 API 开发方式
参考:https://tech.meituan.com/koa-restql.html 在现代的业务系统中,后端开发工作基本上可以被拆分为三项: 接口鉴权.例如判断是不是当前系统的用户,以及该用户是否 ...
- unity图形圆形展开
脚本如下: using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngi ...
- Jmeter接口测试(三)接口测试实践
Jmeter 脚本编写一般分五个步骤: 1. 添加线程组 2. 添加 http 请求 3. 在 http 请求中写入接入 url.路径.请求方式和参数 4. 添加查看结果树 5. 调用接口.查看返回值 ...
- axios封装(二)队列管理
在某些特定的场景(比如 即时搜索 ,表格分页),会频繁的发起ajax请求,而由于ajax是异步API,所以返回的时序并不能够保证,这时候就需要实现一个ajax队列,在相同的请求发起时,取消处理上一个请 ...
- windows下sublime text的node.js开发环境搭建
首先安装sublime text3,百度一堆,自己找吧.理论上sublime text2应该也可以.我只能说一句:这个软件实在是太强悍了. 跨平台,丰富的插件体系,加上插件基本上就是一个强悍的ide了 ...
- scikit-learn使用PCA降维小结
本文在主成分分析(PCA)原理总结和用scikit-learn学习主成分分析(PCA)的内容基础上做了一些笔记和补充,强调了我认为重要的部分,其中一些细节不再赘述. Jupiter notebook版 ...