C++之异常处理

目录

一、C语言处理错误

1、终止程序

2、返回错误码

二、C++异常

异常的抛出和匹配原则

异常安全

异常规范

异常优缺点


一、C语言处理错误

传统处理错误的两种方式:

1、终止程序

使用assert是直接终止程序,包含头文件assert.h即可

缺点:出现错误直接终止程序,用户使用起来比较难受

2、返回错误码

这里的错误码在Linux中用的比较多,Linux底层就是用C语言写的

缺点:错误码比较多,出现错误后需要自己去查找对应的错误,


二、C++异常

异常是一种处理错误的方式

异常需要用到下面三个关键字:throw、catch、try

throw:当问题出现时,程序会抛一个异常

catch:catch是捕捉异常的类型

try:try是捕获的一段区域,后面跟着一个或多个catch块

下面举个简单的除数为0抛异常的例子:

先执行main函数,进入try,执行Test(),输入a、b,再进入Div函数中,判断除数即b是否为0,如果为0,则直接throw错误信息到main函数的catch语句中,打印出来:

如果输入的是正常数字,那么进入Div函数后,执行else语句,再返回到Test函数,再返回到main函数,接下来不执行catch语句,直接跳过catch语句,到return 0:


异常的抛出和匹配原则

1、异常是通过抛出对象而引发的,该对象的类型决定了应该激活哪个catch的处理代码。

例如上面的代码如果多一个catch(int err) { cout << err << endl; },现在有两个catch语句,编译器会根据throw的类型决定进入那个catch语句

2、被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的那一个。

如果改变一下上面的代码:

我们在Test函数中,也加了try,catch语句,这时如果出现除0错误,throw会往回找,谁在这个调用链中离抛异常位置最近,就执行谁的catch语句,结果如下:

可见执行的是Test函数的catch语句

但是需要注意的是,如果Test函数有catch语句,但是与throw的类型不匹配,这时也不会执行Test的catch语句,需要类型匹配

如果出现特殊情况,没有一个函数中的catch与throw的类型匹配,则会直接报错,终止程序,所以异常是必须被捕获的


3、catch(...)可以捕获任意类型的异常,缺点是不知道异常错误是什么。

由于上面说到的,异常必须被捕获,但是担心出现未捕获的异常而导致程序直接崩溃,所以给最后加了一个保险的catch语句,即:catch(...),用于捕获任意类型的异常,当然优先捕获前面的异常,都匹配不上,才会匹配catch(...)

输入5 0,发生除0错误,但是没有类型匹配的catch语句,所以执行catch(...),打印出了未知错误


4、抛出异常对象后,会生成一个异常对象的拷贝,因为抛出的异常对象可能是一个临时对象, 所以会生成一个拷贝对象,这个拷贝的临时对象会在被catch以后销毁。

抛异常一般都会抛一个对象,这个对象一般都是被定义出来的,假设自己写一个Exception类,里面有错误信息与错误编号:

运行结果如下,既能打印出错误信息,又能打印出错误编号:

而main函数中的const Exception& e,也并不是引用的Div函数中创建的Exception e("发生除0错误", 2)这个e对象

因为这个e对象是临时对象,出了作用域会被销毁,所以main函数中引用的是Exception e这个e对象的拷贝对象


5、实际中抛出和捕获的匹配原则有个例外,并不都是类型完全匹配,可以抛出的派生类(子类)对象, 使用基类(父类)捕获

之所以有这个原则,是因为如果一个项目非常大,分了很多个小组做这个项目,每个小组都抛一个异常,那catch这里语句会非常多,不利于使用,所以引出了这个原则,在公司中非常有用

抛派生类对象,用基类捕获,前面学过赋值兼容转换,可以让派生类进行切割/切片处理,从而让基类捕获,所以不管多少人想要抛异常,只要继承统一的一个基类,这时只需要捕获这个基类就达到目的了

try中先调用TestAdd,然后抛AddErr异常

这里的what使用了多态的语法,父类子类都实现了what

抛异常的是子类用父类捕获,子类对象进入catch (const Exception& e)中,切片处理,调用子类的what函数,结果为:


异常安全

不要在构造函数中抛异常,否则可能导致对象不 完整或没有完全初始化

不要在析构函数内抛出异常,否则可能导致资源泄漏

C++中异常经常会导致资源泄漏的问题,比如在new和delete中抛出了异常,导致内存泄漏,死锁等问题,C++经常使用RAII来解决以上问题,关于RAII在接下来的智能指针博客进行讲解。


异常规范

C++98有下面的异常规范,需要注意的是这里的异常规范并不是强制的

①异常规范是为了让使用者知道函数可能抛出的异常有哪些,例如:

void test() throw(x, y);

表示test函数,可能会抛x/y的异常

②函数的后面接throw(),表示函数不抛异常

void test() throw();

表示test函数,不会抛异常

③若无异常接口声明,则此函数可以抛掷任何类型的异常

因为异常规范并不是强制的

④C++11新增关键字noexcept,函数的后面接throw(),表示函数不抛异常:

void test() noexcept;

表示test函数,不会抛异常


异常优缺点

优点:

1、异常相比错误码的方式可以清晰准确的展示出错误的各种信息,可以帮助我们更好的定位程序的bug。

2、返回错误码的传统方式如果返回了错误,那么我们得层层返回错误,最外层才能拿到错误,而如果是异常体系,抛出的异常异常会直接跳到main函数中catch捕获的地方,main函数会直接处理错误。

3、很多的第三方库都包含异常,比如boost、gtest、gmock等等常用的库,那么我们使用它们也需要使用异常。

4、部分函数使用异常更好处理,比如引用返回的函数(类似T&),不使用异常的话,出现越界等错误时只能终止程序

缺点:

1、异常会导致程序的执行流乱跳,因为throw不会一层层的执行

2、C++没有垃圾回收机制,资源需要自己管理。容易导致内存泄漏、死锁等异常安全问题,需要使用RAII来处理资源的管理问题

3、C++标准库的异常体系定义得不好,所以大家各自定义各自的异常体系,非常的混乱。

4、异常尽量规范使用,否则捕获时非常混乱

总而言之:异常是利大于弊的,是建议使用时规范使用


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/154587.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NEFTune: 通过简单的噪声提升指令精调效果

NEFTune指的是Noise Embedding Finetuning&#xff08;噪声嵌入精调&#xff09;&#xff0c;提出自论文&#xff1a;NEFTune: NOISY EMBEDDINGS IMPROVE INSTRUCTION FINETUNING。 NEFTune方法的原理仅使用一句话就可以描述清楚&#xff1a;在finetune过程的词向量中引入一些…

众安保险面试题

文章目录 1.说一下Java内存模型?2.List、Set、Map的区别?3.介绍一下设计模式?4.MySQL存储结构?5.索引失效的场景?6.为什么使用函数索引会失效?7.Spring事务有哪两种?7.1 编程式事务@RestController7.2 声明式事务8.@Transactional实现原理?9.事务如何合并@Transactiona…

es head 新增字段、修改字段、批量修改字段、删除字段、删除数据、批量删除数据

目录 一、新增字段 二、修改字段值 三、批量修改字段值 ​四、删除字段 五、删除数据/文档 六、批量删除数据/文档 一、新增字段 put http://{ip}:{port}/{index}/_mapping/{type} 其中&#xff0c;index是es索引、type是类型 数据&#xff1a; {"_doc"…

听GPT 讲Rust源代码--library/core/src(7)

题图来自 Hello, crustaceans.[1] File: rust/library/core/src/ptr/metadata.rs 在Rust的源代码中&#xff0c;rust/library/core/src/ptr/metadata.rs 文件的作用是定义了与指针&#xff08;ptr&#xff09;和元数据&#xff08;metadata&#xff09;相关的结构体和 trait&am…

C#源代码生成器深入讲解二

在阅读本文前需掌握源代码生成器相关知识C#源代码生成器深入讲解一 C#源代码生成器深入讲解二—增量生成器 源代码生成器有个非常大的弊病&#xff0c;每次都会遍历所有的语法树来分析,这样就有个问题&#xff0c;每次可能只修改了很少一部分或者只有很少一部分的代码需要分析…

异行星平台--CRM系统搭建

使用异行行低代码平台搭建的CRM系统。CRM系统中&#xff0c;包括“客户”、“商机”、“合同”、“回款”、“开票”、“营销”、“回访”、“产品”、“联络人”、“销售订单”、“线索”。 “管理后台”可能是指一个用于管理后台系统的应用&#xff0c;可能包括对各种功能和数…

基于django电影推荐系统

基于django电影推荐系统 摘要 该Django电影推荐系统是一个简单而基础的框架&#xff0c;旨在展示系统的基本组件。系统包括两个主要模型&#xff0c;即Movie和Rating&#xff0c;用于存储电影信息和用户评分。视图层包括展示电影列表和电影详情的功能&#xff0c;使用模板进行页…

从底层认识哈希表【C++】

目录 一. unordered系列关联式容器 二. unordered_map的文档介绍 接口使用 三. 底层实现 &#xff08;1&#xff09;哈希概念 例&#xff1a; &#xff08;2&#xff09;哈希冲突 &#xff08;3&#xff09;冲突解决 1.闭散列​​​​​​​ 闭散列框架 插入 查找 删除 2.开散…

虾皮店铺所有商品数据接口(shopee.item_search_shop)

虾皮店铺所有商品数据接口可以提供丰富的电商数据&#xff0c;包括商品数据、订单数据、会员数据、评价数据等。以下是具体的介绍&#xff1a; 商品数据&#xff1a;虾皮提供了商品的基本信息&#xff0c;包括商品名称、描述、规格、价格、销量、库存等信息。此外&#xff0c;…

【网络知识必知必会】再谈Cookie和Session

文章目录 前言1. 回顾 Cookie1.1 到底什么是 CookieCookie 的数据从哪里来Cookie 的数据长什么样Cookie 有什么作用Cookie 到哪里去Cookie 怎么存储的 2. 理解 Session3. Cookie 和 Session 的区别总结 前言 在讲 HTTP 协议时, 我们就谈到了 Cookie 和 Session, 当时我们只是粗…

【部署篇】Docker配置MySQL容器+远程连接

一、前言 上篇文章在部署nestjs时&#xff0c;由于docker访问不了主机的localhost&#xff0c;所以无法连接主机数据库。所以我们只能在docker中额外配置一个数据库&#xff0c;映射到主机上&#xff0c;然后可以通过ip地址访问。 在本篇文章我们会在docker中创建一个mysql&a…

Logback 日志格式参数说明

打印日志格式&#xff1a; <property name"LOG_PATTERN" value"[${APP_NAME} ${SERVER_IP}:${SERVER_PORT}] %d{yyyy-MM-dd HH:mm:ss.SSS} %level ${PID} [%X{traceId}-%X{spanId}] [%thread] %logger %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/&g…

这7个“小毛病”项目经理必须克服

大家好&#xff0c;我是老原。 项目经理干项目可能不在行&#xff0c;但“踩坑”、“背锅”一定在行。 当上项目经理不容易&#xff0c;当好项目经理更不容易&#xff0c;有永远填不完的坑和背不完的锅。 如果要问项目经理都踩过哪些坑&#xff0c;那真的是太多了&#xff0…

【邻接表,图的邻接表存储表示】

文章目录 邻接表无向图有向图图的邻接表存储表示&#xff1a;图的邻接表的弧&#xff08;边&#xff09;的结点结构 邻接矩阵的好处&#xff1a; 1.直观&#xff0c;简单&#xff0c;好理解。 2.方便检查任意一对顶点间是否存在边 3.方便找到任一顶点的所有“邻接点”&#xff…

思考如何完成一个审批流

思考如何完成一个审批流 这篇文章&#xff0c;可能没有太多的干货&#xff0c;只是对于自己做过项目的一个反思与整理&#xff0c;同时&#xff0c;让这篇文章暴露在公共视野&#xff0c;虚心接受批评指导&#xff0c;向各位前辈同仁进行学习。 如果此文又不当之处&#xff0c;…

MIB 操作系统Lab: Xv6 and Unix utilities(1)boot xv6

从github中下载xv6代码 $ git clone git://g.csail.mit.edu/xv6-labs-2023 $ cd xv6-labs-2023 编译和运行xv6: $ make qemu 如果在终端输入ls命令&#xff0c;能看到输出。 大多数都是可以直接运行的命令。 xv6没有ps命令&#xff0c;但是可以输入ctrl-p可以看到进程的信…

【C语言】动态内存管理

简单不先于复杂&#xff0c;而是在复杂之后 文章目录 1. 为什么存在动态内存分配2. 动态内存函数的介绍2.1 [malloc ](http://www.cplusplus.com/reference/cstdlib/malloc/?kwmalloc)和 [free](https://cplusplus.com/reference/cstdlib/free/)2.2 [calloc](https://cplusplu…

历年国自然标书申请 面上项目614份 2001-2019年 面上标书

这里列举几例 清华任丰原 哈尔滨 杨宝峰 # 关注微信&#xff1a;生信小博士&#xff0c;10元领取 关注微信之后&#xff0c; 点开付费合集即可领取

C51--WiFi模块ESP8266--AT指令

ESP8266 面向物联网应用的&#xff0c;高性价比、高度集成的WiFi MCU 简介&#xff1a; 高度集成&#xff1a; ESP8266EX集成了32位Tensilica 处理器、标准数字外设接口、天线开关、射频balun、功率放大器、底噪放大器、过滤器和电源管理模块&#xff0c;可将所占的PCB空间降…

Jetson orin nano配置深度学习环境

Jetson orin nano是一块比较新的板子&#xff0c;装的是Ubuntu20.04系统&#xff0c;与普通x86_64不同&#xff0c;它是ARM64平台&#xff0c;网上的教程不是很多。 一、Jeston Orin Nano介绍 2022年GTC&#xff0c;NVIDIA 宣布Jetson Orin Nano系列系统模块&#xff08;SoM&a…