探索c++中的异常处理机制(完结版)

c++中的异常捕获

传统的C语言错误判断

1.assert断言, 缺点:直接终止程序
2.errno错误, 缺点:返回错误码, 要去找对应的错误码描述

多数是errno形式, 严重错误会进行断言

c++异常概念:

try catch 捕获异常
throw关键字, 抛出任何类型的异常

现有下面的函数:

在这里插入图片描述
显示结果:

在这里插入图片描述
这个异常可以在任何时候进行捕获:
比如, 中转函数调用也能捕获:
在这里插入图片描述
在这里插入图片描述

异常导致的安全问题

抛异常之后, 此异常代码之后的语句不会执行, 但是他也不会终止, 而是继续完成其他函数或者是类对象的析构,且在析构这些完成之后才显示出异常信息,这边就因为异常导致了执行流的跳跃,假设跳过的内容刚好是new之后对内存的delete,就会导致异常安全问题,看下文

在这里插入图片描述
在这里插入图片描述
异常信息与catch类型不匹配也会捕获失败
当使用string抛异常时, 返回的是他的拷贝
在这里插入图片描述
实际抛出s的拷贝, 这边生成的拷贝在内部会调用移动拷贝
有时, 抛出的异常可能未在我们的预料之内, 所以使用catch ( . . . )捕获未知异常

在这里插入图片描述
在继承多态中:
在这里插入图片描述
当抛出派生类对象, 只需要捕获这个父类即可

在实际工程中, 错误的描述包含最重要的两个信息, 错误码和错误描述, 以及SQL相关的内容(对应异常的各类信息)也会进行记录
比如,在一个完整的服务体系中:
exception(异常) — 父类
sqlexception(sql异常) — 继承exception父类
cacheexception(缓存异常) — 继承exception父类

每个类中都对what()什么异常的这个方法进行重写

在main函数中, 产生抛出异常的方式被父类捕获, 然后父类调用该子类对象的方法, 对应的错误描述对应的信息
在这里插入图片描述

异常体系

c++标准的异常体系
在这里插入图片描述
一般将父类的析构函数写成是多态, 指向父类调父类, 指向子类调用子类

在这里插入图片描述

异常安全

在这里插入图片描述
这边因为Division函数异常, delete没有被执行,导致内存泄露

解决方式1:
在所有写new delete的地方进行 try catch

在这里插入图片描述

解决方式2:(方便)

在这里插入图片描述

这只是一种array的new, 但当有多个array被new时, 这个错误就会形成嵌套的try catch, 这个问题下节智能指针来解决

c++98异常规范:

一般来说可以不写, 但是也没有限制, 希望写 可能的异常
在这里插入图片描述
明确知道这个异常不存在, 但是写上去也没有错, 因为编译器也不确定在将来的调用中, 会不会有这个异常发生
在这里插入图片描述
在异常时, throw()表示无异常, 但是实际这个函数有异常, 可以看到这个规则如同形同虚设, 但是建议写一下正确的异常, 而不是像下面这样:

在这里插入图片描述总结:

在这里插入图片描述

在c++11中, 当你确定没有异常时, 加noexcep关键字,

但是在明确有异常的函数加noexcept会将抛异常的机制进行忽略, 跟没加try catch一样,即使加try catch也会忽略
在右有异常时, 也就不要管,写好自己的try catch就好了, 不用像c++98那样,当然也兼容那种写法, 只是不推荐

异常的优缺点:

优点: 更清晰的展示错误的信息
在函数调用链很长的函数栈帧中, 可以直接跳到处理错误的地方
第三方库, boost gtest, gmock的使用, 也需要使用异常
部分异常的处理方式不方便使用返回值的形式,如 operator[](size_t pos)

缺点:
执行流乱跳
性能开销,现代硬件下可以忽略不计
易导致内存泄漏, 死锁问题
标准异常体系十分不好, 非常混乱
异常规范尽量使用, 都则后果不堪设想

ps: 当未知异常发生, 就会调用这个函数
在这里插入图片描述

喜欢不防来个三连支持一下~~~

  • 20
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

温有情

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值