C++的异常机制底层原理与实际应用详细说明

我们在对 vector 做 push 操作的时候 , 或者对某个指针做 new 操作的时候 , 如果没有做异常处理 , 一旦系统内存不够用了 , 程序是会被 terminate 掉的 。这就要求我们熟悉 C++++ 异常 , 保证日常开发中能正确处理它 。本文主要介绍C++ 异常机制的底层原理与实际应用 , 通俗易懂 , 快来读一读吧 。
以下是正文
C++异常机制概述
异常处理是C++的一项语言机制 , 用于在程序中处理异常事件 。异常事件在 C++ 中表示为 异常对象。异常事件发生时 , 程序使用throw关键字抛出异常表达式 , 抛出点称为异常出现点 , 由操作系统为程序设置当前异常对象 , 然后执行程序的当前异常处理代码块 , 在包含了异常出现点的最内层的 try 块 , 依次匹配catch语句中的异常对象(只进行类型匹配 , catch参数有时在 catch 语句中并不会使用到) 。若匹配成功 , 则执行 catch 块内的异常处理语句 , 然后接着执行 try. 。.catch. 。. 块之后的代码 。如果在当前的 try. 。.catch. 。. 块内找不到 匹配 该异常对象的catch语句 , 则由更外层的 try. 。.catch. 。. 块来处理该异常;如果当前函数内所有的 try. 。.catch. 。. 块都不能匹配该异常 , 则递归回退到调用栈的上一层去处理该异常 。如果一直退到主函数 main() 都不能处理该异常 , 则调用系统函数 terminate() 终止程序 。
一个最简单的 try. 。.catch. 。. 的例子如下所示 。我们有个程序用来记班级学生考试成绩 , 考试成绩分数的范围在 0-100 之间 , 不在此范围内视为数据异常:
int main(){ int score=0; while (cin 》》 score) { try { if (score 》 100 || score 《 0) { throw score; } //将分数写入文件或进行其他操作 } catch (int score) { cerr 《《 “你输入的分数数值有问题 , 请重新输入!”; continue; } }}
throw 关键字
在上面这个示例中 ,  throw 是个关键字 , 与抛出表达式构成了 throw 语句 。其语法为:
throw 表达式;
throw 语句必须包含在 try 块中 , 也可以是被包含在调用栈的外层函数的 try 块中 , 如:
//示例代码:throw包含在外层函数的try块中void registerScore(int score){ if (score 》 100 || score 《 0) throw score; //throw语句被包含在外层main的try语句块中 //将分数写入文件或进行其他操作}int main(){ int score=0; while (cin 》》 score) { try { registerScore(score); } catch (int score) { cerr 《《 “你输入的分数数值有问题 , 请重新输入!”; continue; } }}
执行 throw 语句时 , throw 表达式将作为对象被复制构造为一个新的对象 , 称为异常对象 。异常对象放在内存的特殊位置 , 该位置既不是栈也不是堆 , 在 window 上是放在线程信息块 TIB 中 。这个构造出来的新对象与本级的 try 所对应的 catch 语句进行 类型匹配  , 类型匹配的原则在下面介绍 。

C++的异常机制底层原理与实际应用详细说明

文章插图
定义变量 a 时调用了默认构造函数 , 使用 a 初始化异常变量时调用了复制构造函数 , 使用异常变量复制构造 catch 参数对象时同样调用了复制构造函数 。三个构造对应三个析构 , 也即 try 语句块中局部变量 a 自动被析构了 。然而 , 如果 a 是在自由存储区上分配的内存时:
int main(){ try { A * a= new A; throw *a; } catch (A a) { ; } getchar(); return 0;}
程序运行结果:
C++的异常机制底层原理与实际应用详细说明 C++的异常机制底层原理与实际应用详细说明

文章插图

    推荐阅读