C++ 语法——C++11异常
一、异常的概念及使用1.1 异常的概念异常处理机制允许程序中独立开发的部分能够在运行时就出现的问题进行通信并做出相应的处理异常使得我们能够将问题的检测与解决问题的过程分开程序的一部分负责检测问题的出现然后解决问题的任务传递给程序的另一部分检测环节无须知道问题的处理模块的所有细节。C 语言主要是通过错误码的形式处理错误错误码本质就是对错误信息进行分类编号拿到错误码以后还要去查询错误信息比较麻烦。异常时抛出一个对象这个对象可以涵盖更全面的各种信息。1.2 异常的抛出和捕获程序出现问题时我们通过抛出 (throw) 一个对象来引发一个异常该对象的类型以及当前的调用链决定了由哪个 catch 的处理代码来处理该异常。被选中的处理代码是调用中与该对象类型匹配且离抛出异常位置最近的那一个。根据抛出对象的类型和内容程序的抛出异常部分告知异常处理部分到底发生什么错误。当 throw 执行时throw 后面的语句将不再执行。程序的执行从 throw 位置跳到与之匹配的 catch 模块catch 可能是同一函数中的一个局部 catch也可能是调用链中另一个函数中的 catch 控制权从 throw 位置转移到了 catch 的位置。这里有两个重要的含义1、沿着调用链的函数可能提早退出。2、一旦程序开始执行异常处理程序沿着调用链创建的对象都将被销毁。抛出异常对象后会生成一个异常对象的拷贝因为抛出的异常对象可能是一个局部对象所以会生成一个拷贝对象这个拷贝对象会在 catch 子句后销毁。1.3 栈展开抛出异常后程序暂停当前函数的执行开始寻找与之匹配的 catch 子句首先检查 throw 本身是否在 try 块内部如果在 try 块内部则查找匹配的 catch 语句如果有匹配的则跳到 catch 的地方进行处理。如果当前函数没有 try / catch 语句或者有 try / catch 子句但不匹配则退出房当前函数继续在外层调用函数链中查找上述查找的 catch 过程被称为栈展开。如果到达 main 函数依旧没有找到匹配的 catch 子句程序就会调用标准库的 terminate 函数终止程序如果找到匹配的 catch 子句处理后catch 子句代码继续执行。1.4 查找匹配的处理代码一般情况下抛出对象和 catch 是类型完全匹配的如果存在多个类型匹配的就选择离他位置更近的那个。但是也有一些例外允许从非常量向常量的类型转换也就是权限缩小允许数组转换成指向数组元素类型的指针函数被转换成指向函数的指针允许从派生类向基类的转换这个点非常实用实际中继承体系基本都是用这个方式设计的。如果到 main 函数异常仍就没有被匹配就会终止程序不是发生严重错误的情况下我们是不期望程序终止的所以一般 main 函数中最后都会使用 catch(…)它可以捕获任意类型的异常但是是不知道异常错误是什么。1.5 异常重新抛出有时 catch 到一个异常对象后需要对错误进行分类其中的某种异常需要进行特殊的处理其他错误则重新抛出给外层的调用链处理。捕获后需要重新抛出直接 throw就可以把捕获的对象直接抛出。二、标准库的异常https://legacy.cplusplus.com/reference/exception/exception/C 标准库也定义了一套自己的异常继承体系库基类是 exception所以我们日常写程序需要在主函数捕获 exception 即可要获取异常信息调用 what 函数what 是一个虚函数派生类可以重写。