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 兼容性层)…...
个人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可以…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
