1,问题:

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

1,不处理,则崩溃;

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

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

4,异常的最终处理编程实验:

 #include <iostream>

 using namespace std;

 class Test
{
public:
Test()
{
cout << "Test()";
cout << endl;
} ~Test()
{
cout << "~Test()";
cout << endl;
}
}; int main()
{
static Test t; // BCC Test();
// VC 2010 Test();
// G++ Test(); throw ; // BCC Abnormal program termination;
// VC 对话框弹出来;
// G++ terminate called after throwing an instance of 'int'; return ;
}

1,有了线索,main() 函数中抛出的异常也许会被一个最终的函数处理;

5,异常无法被处理的情况:

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

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

1,三款编译器在 terminate() 函数内部实现上面有点儿差异;

2,比如打印字符串提示当前程序出来异常,弹出对话框告诉用户当前应程序要异常终止(实际还没终止);

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

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

1,C++ 可以自定义结束函数,自定义最终处理异常的函数来替换预定义的 terminate();

6,terminate() 函数的替换:

1,自定义一个无返回值无参数的函数;

1,不能抛出任何异常;

1,最后处理异常的函数了,所以不能抛出任何异常;

2,必须以某种方式结束当前程序;

1,没有做到这一点儿,程序出现什么样的行为就不得而知了,当然 Windows 和 Linux 系统会将这个程序自动终止;

2,调用 set_terminate() 设置自定义的结束函数;

1,参数类型为 void(*)();

1,函数指针,没有参数、没有返回值;

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

7,自定义结束函数编程实验:

 #include <iostream>
#include <cstdlib>
#include <exception> // C++ 标准库中与异常相关的头文件; using namespace std; void my_terminate()
{
cout << "void my_terminate()" << endl;
exit(); // 结束当前的程序;可以确保所有的全局对象和静态局部对象全部都正常析构;
// abort(); // “已放弃”是这个函数打印出来的,这个函数是异常终止一个程序,并且异常终止的时候不会调用任何对象的析构函数;
} class Test
{
public:
Test()
{
cout << "Test()";
cout << endl;
} ~Test()
{
cout << "~Test()";
cout << endl;
}
}; int main()
{
set_terminate(my_terminate); static Test t; throw ; return ;
}

1,打印结果:

1,exit(1) 的时候:

Test()

void my terminate()

~Test()

2,abort() 的时候:

Test()

void my terminate()

已放弃

2,在 main() 函数中扔出的异常如果没有被处理,会被最终的一个全局结束函数处理掉;

3,C++ 编译器之间存在差异;

8,问题:

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

1,前面说有可能导致资源无法释放,内存泄漏等;

2,这里有两点:

1,析构函数是释放资源的地方,如果抛出异常,有可能导致资源无法正确的释放;

2,在析构函数中抛出异常有可能导致全局的结束函数 terminate() 被重复的调用,这是很可怕的,有可能让我们的系统进入一个不稳定的状态;

2,析构函数抛出异常编程实验:

 #include <iostream>
#include <cstdlib>
#include <exception> using namespace std; void my_terminate()
{
cout << "void my_terminate()" << endl;
// exit(1);
abort();
} class Test
{
public:
Test()
{
cout << "Test()";
cout << endl;
} ~Test()
{
cout << "~Test()";
cout << endl; throw ;
}
}; int main()
{
set_terminate(my_terminate); static Test t; throw ; return ;
}

1,打印结果:

1,Test()

void my terminate()  // main() 中 throw 1 抛出异常后第一次执行 my_terminate() 函数的结果;

~Test()  // 调用 exit(),执行析构函数;

void my terminate()  // 在执行析构函数的时候,再次扔出异常 throw 2,第二次执行 my_terminate() 函数;

2,my_terminate() 函数:

1,作为最后一个被调用的异常处理函数,任务是很重的;

2,要负责进行应用程序级别的资源释放;

3,第一次调用的时候,所有的资源已经被释放完了,第二次调用就类似对堆空间的内存第二次释放,造成应用程序的不稳定,因为这里 Linux 系统非常稳定,会帮我们处理好连续释放资源的问题;

4,如果进行嵌入式开发,操作系统就不见得有这样的能力对每一个系统做这样的监控,产生的行为使未定义的;

5,这也解释了 C++ 默认调用的是 abort() 而不是 exit(1),因为 abort() 直接的强制结束当前的应用程序,不会调用析构函数,就是拍析构函数中扔出异常;

9,小结:

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

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

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

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

C++异常处理的深入理解的更多相关文章

  1. Java异常处理机制 —— 深入理解与开发应用

    本文为原创博文,严禁转载,侵权必究! Java异常处理机制在日常开发中应用频繁,其最主要的不外乎几个关键字:try.catch.finally.throw.throws,以及各种各样的Exceptio ...

  2. 对try-catch-finally异常处理的最新理解

    try{ ...... }catch(......){ }finally{ ...... } 这个结构是用来处理Java所有可能出现的异常的,这个我很早其实就已经学过,不过最近看了个视频,感觉自己虽然 ...

  3. 谈谈你对Java异常处理机制的理解

    先谈谈我的理解:异常处理机制可以说是让我们编写的程序运行起来更加的健壮,无论是在程序调试.运行期间发生的异常情况的捕获,都提供的有效的补救动作,任何业务逻辑都会存在异常情况,这时只需要记录这些异常情况 ...

  4. 面向对象的异常处理之深入理解java异常处理机制

    什么是异常? 异常是对问题的描述,将问题的对象进行封装: 异常体系的特点:异常体系中的所有类以及建立的对象: 都具有可抛性,也就是说可以被throw和throws关键字所操作,只有异常体系具有该特点: ...

  5. 从C#到Objective-C,循序渐进学习苹果开发(4)--代码块(block)和错误异常处理的理解

    本随笔系列主要介绍从一个Windows平台从事C#开发到Mac平台苹果开发的一系列感想和体验历程,本系列文章是在起步阶段逐步积累的,希望带给大家更好,更真实的转换历程体验.本文继续上一篇随笔<从 ...

  6. aop原理及理解

    概念 Aspect Oriented Programming,面向切面编程,实际上它是一个规范.一种设计思路,总之是抽象的. 先上图 使用目的 从项目结构上来说 对业务逻辑的各个部分进行隔离,降低业务 ...

  7. 第6章 AOP与全局异常处理6.1-6.4 慕课网微信小程序开发学习笔记

    第6章 AOP与全局异常处理 https://coding.imooc.com/learn/list/97.html 目录: 第6章 AOP与全局异常处理6-1 正确理解异常处理流程 13:236-2 ...

  8. 第6章 AOP与全局异常处理6.5-6.11 慕课网微信小程序开发学习笔记

    https://coding.imooc.com/learn/list/97.html 目录: 第6章 AOP与全局异常处理6-1 正确理解异常处理流程 13:236-2 固有的处理异常的思维模式与流 ...

  9. 面向对象程序设计-C++ Stream & Template & Exception【第十五次上课笔记】

    这是本门<面向对象程序设计>课最后一次上课,刚好上完了这本<Thinking in C++> :) 这节课首先讲了流 Stream 的概念 平时我们主要用的是(1)在屏幕上输入 ...

随机推荐

  1. C# 下载PDF文件(http与ftp)

    1.下载http模式的pdf文件(以ASP.NET为例,将PDF存在项目的目录下,可以通过http直接打开项目下的pdf文件) #region 调用本地文件使用返回pdfbyte数组 /// < ...

  2. 任务21 :了解ASP.NET Core 依赖注入,看这篇就够了

    DI在.NET Core里面被提到了一个非常重要的位置, 这篇文章主要再给大家普及一下关于依赖注入的概念,身边有工作六七年的同事还个东西搞不清楚.另外再介绍一下.NET  Core的DI实现以及对实例 ...

  3. 【学习总结】cpu缓存

    参考链接: cpu缓存java性能问题初探 高速缓存 在内存与cpu寄存器之间,还有一块区域叫做cpu高速缓存,即我们常常说的cache. cache分为L1.L2.L3三级缓存,速度递减,离cpu越 ...

  4. JS中对象数据类型的基本结构和操作

    Object类型 ECMAScript中的队形其实就是一组数据和功能的集合.对象可以通过执行new操作符后跟要创建的对象类型的名称来创建.而创建Object类型的示例并为其添加属性和(或)方法,就可以 ...

  5. React(2) --super关键字

    参考:http://www.phonegap100.com/thread-4911-1-1.html Es6中的super可以用在类的继承中,super关键字,它指代父类的实例(即父类的this对象) ...

  6. 从零开始之uboot、移植uboot2017.01(二、从入口分析流程)

    原创: To_run_away 从零开始学linux 本节的开始之前,先看一下uboot的链接脚本. 一.链接脚本 /* * Copyright (c) 2004-2008 Texas Instrum ...

  7. springboot redis操作

    redis五大类型用法 Redis五大类型:字符串(String).哈希/散列/字典(Hash).列表(List).集合(Set).有序集合(sorted set)五种Controller:@Reso ...

  8. 【leetcode】878. Nth Magical Number

    题目如下: 解题思路:本题求的是第N个Magical Number,我们可以很轻松的知道这个数的取值范围 [min(A,B), N*max(A,B)].对于知道上下界求具体数字的题目,可以考虑用二分查 ...

  9. 为什么js的"关联数组"不能转成json字符串而对象可以?

    定义这么一个js的“关联数组”: var arr = new Array(); arr[; arr[; alert(JSON.stringify(arr)); 得到的结果如图: [] 一句话,你的 a ...

  10. Struts2基础-3 -继承ActionSupport接口创建Action控制器+javaBean接收请求参数+ 默认Action配置处理请求错误 + 使用ActionContext访问ServletAPI

    1.目录结构及导入的jar包 2.web.xml 配置 <?xml version="1.0" encoding="UTF-8"?> <web ...