当前位置: 首页 > news >正文

【C++进阶】异常

在这里插入图片描述

👦个人主页:@Weraphael
✍🏻作者简介:目前学习C++和算法
✈️专栏:C++航路
🐋 希望大家多多支持,咱一起进步!😁
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨


目录

  • 一、C语言传统的处理错误的方式
  • 二、C++异常概念
  • 三、异常的抛出和匹配规则
      • 3.1 异常的抛出和捕获
      • 3.2 异常的重新抛出

一、C语言传统的处理错误的方式

C语言传统的处理错误的方式主要是通过返回值或者全局变量来表示函数执行的状态,但是这种方式存在以下缺陷:

  1. 终止程序。常见的方法就是写一个assert函数或exit函数。缺陷:终止程序的执行,导致程序的崩溃。但是一个程序在运行时需要保持稳定性。举一个例子:大家在使用计算器时,当除数为0时,程序会崩溃吗?显然是不会的,而是会报以下错误信息

在这里插入图片描述

  1. 返回错误码。缺陷:需要程序员自己去查找对应的错误,比较麻烦。

C++针对上面的不足,引入了 异常 的概念,不会终止程序,并且会将错误信息详细介绍。

二、C++异常概念

异常是面向对象语言处理错误的一种方式。当一个函数出现自己无法处理的错误时,可以抛出异常,然后直接或者间接的调用者处理这个错误。

因此C++提供了以下异常相关的关键字

  • throw当问题出现时,程序会抛出一个异常。这是通过使用throw关键字来完成的
  • catch用于捕获异常,可以有多个catch进行捕获
  • trytry块中一般是可能出现异常的代码,它后面通常跟着一个或多个catch块。

注意:可以抛出任意类型的对象。抛出的异常必须捕获。try要和catch匹配使用,catch里的内容抛出异常时才执行,没有异常,不执行。

举一个除数为0的例子:

#include <iostream>
using namespace std;int test()
{int a, b;cin >> a >> b;if (b == 0){// throw用来抛出异常,异常的描述throw "除数不能为0";}return a / b;
}int main()
{try{// try里放会可能出现异常的代码cout << test() << endl;}// catch用来捕获异常catch (const char* a){cout << a << endl;}return 0;
}

【运行结果】

在这里插入图片描述

三、异常的抛出和匹配规则

3.1 异常的抛出和捕获

  1. 异常是通过抛出(throw)对象而引发的,并且抛出的对象可以是任意类型,其对象的类型决定了应该激活哪个catch的处理代码。
#include <iostream>
using namespace std;int test()
{int a, b;cin >> a >> b;if (b == 0){// throw用来抛出异常,异常的描述throw "除数不能为0";}return a / b;
}int main()
{try{// try里放会可能出现异常的代码cout << test() << endl;}// catch用来捕获异常catch (const char* a){cout << a << endl;}catch (int a){cout << a << endl;}return 0;
}

就比如以上代码:throw的对象是字符串类型,因此当出现异常是,它激活的是第一个catch的处理代码,最后一定会输出"除数不能为0"

在这里插入图片描述

注意:如果catch类型和throw对象类型不匹配,会导致捕获失败,编译器就会报错。因此,C++规定:出现异常就必须被捕获

在这里插入图片描述

  1. 选中的处理代码(throw)是调用链中与该对象类型匹配且离抛出异常位置最近的那一个

在这里插入图片描述

【在函数调用链中异常栈展开匹配原则】

  • 首先检查throw本身是否在try块内部,如果是就查找匹配的catch语句。如果有匹配的,则调到catch的地方进行处理;如果没有匹配的catch则退出当前函数栈,继续在调用函数的栈中进行查找匹配的catch。如果到达main函数的栈,依旧没有匹配的,则终止程序,并报错。
  • 上述这个沿着调用链查找匹配的catch子句的过程称为栈展开。所以实际中我们最后都要加一个 catch(...)捕获任意类型的异常,否则当有异常没捕获,程序就会直接终止。
  • 找到匹配的catch子句并处理以后,会继续沿着catch子句后面继续执行。

在这里插入图片描述

  1. catch(...)可以捕获任意类型的异常,问题是不知道异常错误是什么。
  2. 实际中抛出和捕获的匹配原则有个例外,并不都是类型完全匹配,可以抛出的派生类对象,使用基类捕获,这个在实际中非常实用,我们后面会详细讲解这个。

3.2 异常的重新抛出

相关文章:

  • 3D模型格式转换工具HOOPS Exchange对工业级3D产品HOOPS的支持与应用
  • 微服务初始和Nacos安装
  • 11.与JavaScript深入交流-[js一篇通]
  • 报错:Error: error:0308010C:digital envelope routines::unsupported
  • 用 docker 创建 jmeter 容器, 实现性能测试
  • 4.1 Bloom算法
  • 目标检测与图像识别分类的区别?
  • 图的深度优先遍历的六种应用附Java代码
  • 一体化模型图像去雨+图像去噪+图像去模糊(图像处理-图像复原-代码+部署运行教程)
  • (SpringBoot)第二章:Spring创建和使用
  • 矢量图形编辑软件illustrator 2023 mac中文软件特点
  • 微信开放平台账号
  • 0037【Edabit ★☆☆☆☆☆】【修改Bug 2】Buggy Code (Part 2)
  • redis6.0源码分析:简单动态字符串sds
  • 贝叶斯神经网络用于学习曲线的概率预测【ICLR 2017】
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • docker-consul
  • go语言学习初探(一)
  • Java知识点总结(JavaIO-打印流)
  • mongo索引构建
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • quasar-framework cnodejs社区
  • tab.js分享及浏览器兼容性问题汇总
  • Vue2.x学习三:事件处理生命周期钩子
  • Windows Containers 大冒险: 容器网络
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 搭建gitbook 和 访问权限认证
  • 前端攻城师
  • 容器服务kubernetes弹性伸缩高级用法
  • 详解NodeJs流之一
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 一天一个设计模式之JS实现——适配器模式
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • Linux权限管理(week1_day5)--技术流ken
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ​第20课 在Android Native开发中加入新的C++类
  • (42)STM32——LCD显示屏实验笔记
  • (HAL库版)freeRTOS移植STMF103
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程
  • (利用IDEA+Maven)定制属于自己的jar包
  • (六)c52学习之旅-独立按键
  • (生成器)yield与(迭代器)generator
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • .a文件和.so文件
  • .equals()到底是什么意思?
  • .NET Core使用NPOI导出复杂,美观的Excel详解
  • .Net Memory Profiler的使用举例
  • .NET Reactor简单使用教程
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .net开发引用程序集提示没有强名称的解决办法
  • .sys文件乱码_python vscode输出乱码
  • [ Linux Audio 篇 ] 音频开发入门基础知识