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

C++程序设计——异常

一、C++异常概念

        异常处理是一种处理错误的方式,当一个函数发现自己无法处理的错误时,就可以抛出异常,让函数的直接或间接的调用者处理这个错误。

(1)throw:当问题出现时,程序会通过throw关键字抛出异常。

(2)catch:在想要处理问题的地方,异常处理程序通过catch关键字捕获异常,可以有多个catch进行捕获。

(3)try:try块中的代码标识将被激活的特定异常,它后面通常跟着一个或多个catch块。

二、异常的使用

1.异常的抛出和捕获

1.1 异常的抛出和匹配原则

(1)异常是通过抛出对象而引发的,该对象的类型决定了应该激活那个catch的处理代码,即catch捕获的异常类型必须与throw抛出的异常实体类型完全一致,因为这里编译器基本不会进行隐式类型转换。

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

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

(4)catch(...)可以捕获任意类型的异常,但问题是不知道异常错误是什么。

(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)虚构函数负责完成对资源的清理,所以最好不要在析构函数中抛出异常,否则可能导致资源泄漏。

(3)C++中,异常经常会导致资源泄漏问题,比如在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)异常会有一些性能的开销,当然这个开销很小,在现代硬件条件下可以或略不计。

(3)C++没有垃圾回收机制,资源需要自己进行管理。而异常非常容易导致资源泄漏、死锁等异常安全问题。这需要使用RAII来处理资源管理问题。

(4)C++标准库的异常体系定义并不完美,导致大家各自定义各自的异常体系,非常混乱。

(5)异常使用不规范,随意抛异常,会导致外层捕获非常麻烦。所以异常规范主要有两点:①抛出异常的类型都继承自一个基类;②函数是否抛异常,抛出什么异常,都要使用func()throw()的方式进行规范化。但有的编译器又会忽略异常规范,比如VS2019,对于不知情者,可能造成较大困惑。

总结:虽然异常处理比较麻烦,但是总体而言还是利大于弊的。

相关文章:

C++程序设计——异常

一、C异常概念 异常处理是一种处理错误的方式,当一个函数发现自己无法处理的错误时,就可以抛出异常,让函数的直接或间接的调用者处理这个错误。 (1)throw:当问题出现时,程序会通过throw关键字抛…...

2022年第十三届蓝桥杯web开发—东奥大抽奖【题目、附官方解答】

冬奥大抽奖 介绍 蓝桥云课庆冬奥需要举行一次抽奖活动,我们一起做一个页面提供给云课冬奥抽奖活动使用。 准备 开始答题前,需要先打开本题的项目代码文件夹,目录结构如下: ├── css │ └── style.css ├── effect.g…...

一份两年前一个月的工作经历没写在简历上,背调前主动坦白,却被背调公司亮了红灯,到手的offer没了!...

只因为简历上漏写了一份一个月的工作,就被亮了背调红灯,这公平吗?一位网友就被狠狠坑了一把,来看下他的遭遇:他有一份两年前、时长一个月的工作经历没写在简历上,背调前主动和背调公司还有招聘方hr都说了这…...

C++游戏分析与破解方法介绍

1、C游戏简介 目前手机游戏直接用C开发的已经不多,使用C开发的多是早期的基于cocos2dx的游戏,因此我们这里就以cocos2d-x为例讲解C游戏的分析与破解方法。 Cocos2d-x是一个移动端游戏开发框架,可以使用C或者lua进行开发,也可以混…...

食堂总是拥挤不堪?解决用餐拥挤,教你一招

随着近几年科技的快速发展,行业里出现了很多新的名词,比如智慧社区、智慧旅游、智慧建筑,那么智慧食堂是什么呢?它又是如何实现全自助、全智能消费? 在先进的智能技术以及市场需求带动下,智慧食堂经历了由传…...

ubuntu系统安装时 MBR和GPT的区别

主引导记录(Master Boot Record , MBR)是指一个存储设备的开头 512 字节。它包含操作系统的引导器和存储设备的分区表。   全局唯一标识分区表(GUID Partition Table,缩写:GPT)是一个实体硬盘…...

我在windows10下,使用msys64 mingw64终端

系列文章目录 文章目录系列文章目录前言一、MSYS2是什么?前言 msys2官网 MSYS2 (Minimal SYStem 2) 是一个MSYS的独立改写版本,主要用于 shell 命令行开发环境。 同时它也是一个在Cygwin (POSIX 兼容性层&#xff09…...

个人2023FALL CS申请总结(PhD/MPhil/保研夏令营)

个人2023FALL CS申请总结(PhD/MPhil/保研夏令营)写在最前个人BG及申请情况个人BG申请情况MPhilPhD收获一句话总结:心态爆炸没用,脸皮够厚够勇就行 写在最前 真是一场恶战。有几天,我每天早上都海投几封套瓷邮件&…...

【优化算法】使用遗传算法优化MLP神经网络参数(TensorFlow2)

文章目录任务查看当前的准确率情况使用遗传算法进行优化完整代码任务 使用启发式优化算法遗传算法对多层感知机中中间层神经个数进行优化,以提高模型的准确率。 待优化的模型: 基于TensorFlow2实现的Mnist手写数字识别多层感知机MLP # MLP手写数字识别…...

CAM类激活映射 |神经网络可视化 | 热力图

文章目录前言:安装库:分类案例--ResNet50分割案例AttributeError: ‘tuple‘ object has no attribute ‘cpu‘RuntimeError: grad can be implicitly created only for scalar outputsTypeError: cant convert cuda:0 device type tensor to numpy. Use…...

RecyclerView+BaseRecyclerViewAdapterHelper显示不全只显示第一行item的解决问题

RecyclerViewBaseRecyclerViewAdapterHelper显示不全只显示第一行item,我懵了…,我不说多,直接说吧 先看一下适配器代码中的convert()方法: class MineRadioAdapter(layoutResId: Int R.layout.item_my_live) :BaseQuickAdapte…...

解决后端无法对前端的ajax请求重定向

本章目录: 问题描述 AJAX请求后端直接重定向失败解决方案 后端拦截请为响应头添加重定向标志后端拦截器为响应头添加重定向路径前端响应拦截器获取响应头数据,并通过location.href url 完成页面跳转一、问题描述 本来想在拦截器里设置未登录用户访问指…...

【Python】1分钟就能制作精美的框架图?太棒啦

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、准备二、基本使用与例子1.初始化与导出2.节点类型3.集群块4.自定义线的颜色与属性总结前言 Diagrams 是一个基于Python绘制云系统架构的模块,它能…...

淘宝必备的补单技巧及注意事项!

补单,是优化善后的s单。单只是模拟用户的购物习惯,而补单同时还要模拟整个店铺的综合数据,包括点击率、转化率等等,补到略高于同行、竞品的平均数据时,淘宝会判断为买家比较喜欢你的商品,从而给你更多推荐机…...

【实用篇】SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud分布式

文章目录一、服务拆分1.1 服务拆分Demo1.2 微服务远程调用二、Eureka2.1 Eureka原理2.2 Eureka-server服务搭建2.3 eureka-client服务注册2.4 eureka-client服务复制2.5 eureka服务发现三、Ribbon负载均衡3.1 负载均衡原理3.2 负载均衡策略3.3 自定义负载均衡策略3.4 饥饿加载与…...

私人飞机、公务机包机会成为富豪圈的主流出行方式吗?

从炫耀性消费到按需使用,私人飞机的消费群体正在被拓宽,但离“成为主流”还有一段距离。“时间就是金钱”为有钱人消费私人飞机提供合理动机,而这群高净值人群的数量增长则成为撑起市场基本面。据相关数据显示,2018年全球超级富豪…...

Oracle组织架构

组织架构 (一)业务组(BG) (二)法律实体(LE) (三)业务实体(OU) (四)库存组织(INV) …...

最小公倍数

目录 最小公倍数 程序设计 程序分析 最小公倍数 【问题描述】给定两个正整数,计算这两个数的最小公倍数。 【输入形式】输入包含多组测试数据,每组只有一行,包括两个不大于1000的正整数. 【输出形式】 对于每个测试用例,给出这两个数的最小公倍数,每个实例输出一行。…...

二叉树的后序遍历(力扣145)

目录 题目描述: 解法一:递归法 解法二:迭代法 解法三:Morris遍历 二叉树的后序遍历 题目描述: 给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。 示例 1: 输入:root …...

《Effective C++》读书纪实 -- 诸君同享

文章目录《Effective C》是一本经典的C编程指南,共包含50条C编程的最佳实践。 确定你的构造函数的行为 在构造函数中,应该尽可能地避免调用虚函数、非静态成员函数和虚基类的函数。 尽量使用const、enum、inline替换#define 使用const、enum、inline可以…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...

MMaDA: Multimodal Large Diffusion Language Models

CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...