漳州市住房建设局网站,网站一般多长,石家庄制作网站的公司简介,天津seo网站设计一、C异常概念 异常处理是一种处理错误的方式#xff0c;当一个函数发现自己无法处理的错误时#xff0c;就可以抛出异常#xff0c;让函数的直接或间接的调用者处理这个错误。
#xff08;1#xff09;throw#xff1a;当问题出现时#xff0c;程序会通过throw关键字抛…一、C异常概念 异常处理是一种处理错误的方式当一个函数发现自己无法处理的错误时就可以抛出异常让函数的直接或间接的调用者处理这个错误。
1throw当问题出现时程序会通过throw关键字抛出异常。
2catch在想要处理问题的地方异常处理程序通过catch关键字捕获异常可以有多个catch进行捕获。
3trytry块中的代码标识将被激活的特定异常它后面通常跟着一个或多个catch块。
二、异常的使用
1.异常的抛出和捕获
1.1 异常的抛出和匹配原则
1异常是通过抛出对象而引发的该对象的类型决定了应该激活那个catch的处理代码即catch捕获的异常类型必须与throw抛出的异常实体类型完全一致因为这里编译器基本不会进行隐式类型转换。
2被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的哪一个。
3抛出异常对象后会生成一个异常对象的拷贝因为抛出的异常对象可能是一个临时对象所有会生成一个拷贝对象这个拷贝的临时对象会在被catch以后销毁。
4catch(...)可以捕获任意类型的异常但问题是不知道异常错误是什么。
5实际中抛出和捕获的匹配原则有个例外一般不会发生隐式类型转换类型都是完全匹配但是有一个例外就是可以抛出派生类对象使用基类捕获在实际中非常实用。
1.2 函数调用链中异常栈展开匹配原则
1首先检查throw本身是否在try块内部如果是再查找匹配的catch语句如果有匹配的则调到catch的地方进行处理。
2若没有匹配的catch则退出当前函数栈继续在调用函数的栈中进行查找匹配的catch。
3如果到达min函数的函数栈依旧没有匹配成功则终止程序。上述这个沿着调用链查找匹配的catch子句的过程称为栈展开所以实际中我们最后都要加一个catch(...)捕获任意类型的异常否则当有异常没有捕获程序就会之间终止。
4找到匹配的catch子句并处理以后会继续沿着catch子句后面继续执行。
5若一直到main函数中都没有找到对异常的处理则会将异常交给操作系统处理而操作系统会直接终止程序的运行。 2.异常的重新抛出 有可能单个catch不能完全处理一个异常在进行一些校正处理后希望再交给更外层的调用链函数来处理catch则可以通过重新抛出将异常传递给更上层的函数进行处理。
异常的重新抛出throw 直接throw不跟任何内容就是将捕获的异常重新抛出。 3.异常安全
1构造函数负责完成对象的构造和初始化所以最好不要在构造函数中抛出异常否则可能导致对象不完整或没有完全初始化。
2虚构函数负责完成对资源的清理所以最好不要在析构函数中抛出异常否则可能导致资源泄漏。
3C中异常经常会导致资源泄漏问题比如在new和delete中抛出了异常导致内存泄漏在lock和unlock之间抛出了异常导致死锁。C中经常使用RAII来解决以上问题。
4.异常规范
1异常规范说明的目的是为了让函数的使用者知道该函数可能抛出的异常有那些。可以通过在函数的后面接throw(类型)列出该函数可能抛出的所有异常类型。
2 函数的后面接throw()表示该函数不抛出异常。
3若无异常接口声明则此函数可以抛出任何类型的异常。
注意VS2019下忽略了异常规范 三、自定义异常体系 如果一个项目中大家随意抛异常那么外层调用者基本就没办法处理了所以实际中都会定义一套继承的规范异常体系进行异常管理这样大家抛出的都是继承的派生类对象捕获基类对象即可。
四、C标准库的异常体系 C标准库提供了一系列标准的异常我们可以在程序中使用这些标准的异常它们是以父子类层次结构组织起来的 每个异常的说明 五、异常的优缺点
1.异常的优点
1异常对象定义好后相比于错误码的方式可以清晰准确的展示出错误的各种信息甚至可以包含堆栈调用信息可以帮助我们更好的定位程序的错误原因。
2返回错误码的传统方式存在一个较大的问题在函数调用链中深层的函数返回了错误那么得层层返回错误最外层才能拿到错误。
3很多的第三库都包含异常比如boost、gtest、gmock等等那么我们在使用它们时就需要使用异常。
4很多测试框架都使用异常这样能更好的使用单元测试等进行白盒测试。
5部分函数使用异常更好处理比如T operator这样的函数如果pos越界了只能使用异常或终止程序处理没办法通过返回值表示错误。
2.异常的缺点
1异常会导致程序的执行流混乱并且运行时抛出异常就会乱跳导致我们跟踪调试、分析程序时比较困难。
2异常会有一些性能的开销当然这个开销很小在现代硬件条件下可以或略不计。
3C没有垃圾回收机制资源需要自己进行管理。而异常非常容易导致资源泄漏、死锁等异常安全问题。这需要使用RAII来处理资源管理问题。
4C标准库的异常体系定义并不完美导致大家各自定义各自的异常体系非常混乱。
5异常使用不规范随意抛异常会导致外层捕获非常麻烦。所以异常规范主要有两点①抛出异常的类型都继承自一个基类②函数是否抛异常抛出什么异常都要使用func()throw()的方式进行规范化。但有的编译器又会忽略异常规范比如VS2019对于不知情者可能造成较大困惑。
总结虽然异常处理比较麻烦但是总体而言还是利大于弊的。