C++基础与深度解析 | 异常处理 | 枚举与联合 | 嵌套类与局部类 | 嵌套名字空间与匿名名字空间 | 位域与volatile关键字
文章目录
- 一、异常处理
- 二、枚举与联合
- 三、嵌套类与局部类
- 四、嵌套名字空间与匿名名字空间
- 五、位域与volatile关键字
一、异常处理
异常处理用于处理程序在调用过程中的非正常行为。
-
传统的处理方法:传返回值表示函数调用是否正常结束。
例如,返回
0
表示成功,非0
表示失败。这种方法的缺点是函数的返回值被错误处理逻辑占用,不能用于其他目的。这种方法有局限性
-
C++ 中的处理方法:通过关键字 try/catch/throw 引入异常处理机制
通过
try/catch/throw
引入了结构化的错误处理机制,使得错误处理逻辑与正常逻辑分离,提高了代码的可读性和可维护性。C++异常处理的关键组件:
-
throw关键字
throw
关键字用于抛出一个异常。它后面可以跟任意类型的表达式,该表达式的结果将被用作异常对象 -
try块
try
块包含了可能会抛出异常的代码。如果try
块中的代码抛出了异常,那么与之匹配的catch
块将被执行。 -
catch块
catch
块用于捕获并处理异常。可以有多个catch
块来捕获不同类型的异常。 -
异常类
C++标准库中定义了一些基本的异常类,如
std::exception
、std::runtime_error
、std::logic_error
等
-
异常触发时的系统行为—栈展开:
-
抛出异常后续的代码不会被执行
一旦抛出异常,
throw
语句之后的代码将不会被执行。控制流会立即转移到异常处理机制。 -
局部对象会按照构造相反的顺序自动销毁
在栈展开过程中,局部对象(包括由
new
分配的对象)会按照它们构造的相反顺序自动销毁。这是为了保证资源的正确释放,防止内存泄漏。 -
系统尝试匹配相应的 catch 代码段
-
如果找到匹配的
catch
块:- 执行
catch
块中的异常处理逻辑。 - 异常被“捕获”后,
catch
块之后的代码会继续执行。
- 执行
-
如果没有找到匹配的
catch
块:-
栈展开会继续进行,直到找到匹配的
catch
块或者退出当前函数。 -
如果当前函数中没有找到匹配的
块,栈展开会继续,直到:
-
找到一个匹配的
catch
块。 -
达到
main
函数。如果在
main
函数之前的所有函数中都没有找到匹配的catch
块,程序将退出main
函数。如果程序在退出main
函数之前没有捕获到异常,std::terminate
函数将被调用。这通常会导致程序立即终止。
-
-
-
异常对象:
- 系统会使用抛出的异常拷贝初始化一个临时对象,称为异常对象
- 异常对象会在栈展开过程中被保留,并最终传递给匹配的 catch 语句
try / catch语句块:
-
一个 try 语句块后面可以跟一到多个 catch 语句块(至少跟一个)
-
每个 catch 语句块用于匹配一种类型的异常对象
可以有多个
catch
块,每个用于处理不同类型的异常。 -
catch 语句块的匹配按照从上到下进行
catch
块按照它们在代码中出现的顺序(从上到下)进行匹配。一旦找到匹配的异常类型,就执行相应的catch
块,忽略后面的catch
块。 -
使用 catch(…) 匹配任意异常
catch(...)
是一个通用的异常捕获器,它可以捕获任何类型的异常,包括未被前面的catch
块捕获的异常。 -
在 catch 中调用 throw 继续抛出相同的异常
在
catch
块中,可以使用throw;
(不带参数)来重新抛出当前捕获的异常,这将导致继续搜索外层catch
块。
示例:
#include <iostream>struct Str{};
struct Base{};
struct Derive : Base{};void f1()
{int x;Str obj;//throw Derive{}; //打印Derive exception is called in f2 throw Str{}; //打印exception is called in f2
}void f2()
{int x2;Str obj2;try{f1();}catch(Derive& e){std::cout << "Derive exception is called in f2 " << "\n";}catch(Base& e){std::cout << "Base exception is called in f2 " << "\n";}catch(...){std::cout << "exception is called in f2" << "\n";throw; //重新抛出当前捕获的异常}std::cout << "other logic in f2.\n";
}void f3()
{try{f2(); }catch(Str& e){std::cout << "exception is called in f2" << "\n";}
}int main()
{f3();
}
在一个异常未处理完成时抛出新的异常会导致程序崩溃:
- 不要在析构函数或 operator delete 函数重载版本中抛出异常
- 通常来说, catch 所接收的异常类型为引用类型
异常与构造、析构函数:
-
使用 function-try-block保护初始化逻辑
在C++中,function-try-block允许你在函数的初始化列表和函数体中使用
try
和catch
。这在构造函数中特别有用,因为它可以保护对象的初始化代码。示例:
#include <iostream>struct Str {Str() { throw 100; } }class Resource { public:Resource() try : m_str(){}catch(int){std::cout << "Exception is catched at Resource::Resource" << std::endl;throw;}private:Str m_str; };int main() {try{Resource obj; }catch(int){std::cout << "Exception is catched at main" << std::endl;} }
运行结果:
Exception is catched at Resource::Resource Exception is catched at main
-
在构造函数中抛出异常:
-
已经构造的成员对象会被销毁
如果在构造函数中抛出异常,已经构造的成员对象将按照它们构造的相反顺序自动销毁。
-
类本身的析构函数不会被调用
如果异常是在对象的构造过程中抛出的,并且没有被捕获,那么类的析构函数不会被调用。这是因为对象被视为未完全构造,因此析构函数不适用。
-
局部对象的销毁
如果对象是局部的(即在栈上),异常抛出时,局部对象会自动销毁,但不会调用其析构函数。
-
动态分配对象的销毁
如果对象是动态分配的(即使用
new
),在构造函数中抛出异常且未被捕获时,需要手动释放分配的内存,因为析构函数不会被调用。
-
描述函数是否会抛出异常:
-
如果函数不会抛出异常,则应表明,从而为系统提供更多的优化空间
- C++ 98 的方式:
- throw() :表明不会抛出异常
- throw(int, char):表明可能抛出异常,显式给定了要抛出异常的类型
- C++11 后的改进:
- noexcept :表明不会抛出异常
- noexcept(false):表明可能抛出异常,不需要显式给定会抛出哪种类型的异常
- C++ 98 的方式:
-
noexcept
- 限定符:接收 false / true 表示是否会抛出异常
- 操作符:接收一个表达式,根据表达式是否可能抛出异常返回 false/true
- 在声明了 noexcept 的函数中抛出异常会导致 terminate 被调用,程序终止
- 不作为函数重载依据,但函数指针、虚拟函数重写时要保持形式兼容
示例:
#include <iostream>void fun2()
{}void fun() noexcept(noexcept(fun2()))
{fun2();
}int main()
{std::cout << noexcept(fun()) << std::endl;
}
二、枚举与联合
三、嵌套类与局部类
四、嵌套名字空间与匿名名字空间
五、位域与volatile关键字
相关文章:
C++基础与深度解析 | 异常处理 | 枚举与联合 | 嵌套类与局部类 | 嵌套名字空间与匿名名字空间 | 位域与volatile关键字
文章目录 一、异常处理二、枚举与联合三、嵌套类与局部类四、嵌套名字空间与匿名名字空间五、位域与volatile关键字 一、异常处理 异常处理用于处理程序在调用过程中的非正常行为。 传统的处理方法:传返回值表示函数调用是否正常结束。 例如,返回 0 表示…...
番外篇 | 利用华为2023最新Gold-YOLO中的Gatherand-Distribute对特征融合模块进行改进
前言:Hello大家好,我是小哥谈。论文提出一种改进的信息融合机制Gather-and-Distribute (GD) ,通过全局融合多层特征并将全局信息注入高层,以提高YOLO系列模型的信息融合能力和检测性能。通过引入MAE-style预训练方法,进一步提高模型的准确性。🌈 目录 🚀1.论文解…...
python记录之字符串
在Python中,字符串是一种非常常见且重要的数据类型,用于存储文本信息。下面,我们将对Python字符串进行深入的讲解,包括其基本操作、常见方法、格式化以及高级特性。 1. 字符串的创建 在Python中,字符串可以通过单引号…...
Elasticsearch 认证模拟题 - 15
一、题目 原索引 task1 的字段 title 字段包含单词 The,查询 the 可以查出 1200 篇文档。重建 task1 索引为 task1_new,重建后的索引, title 字段查询 the 单词,不能匹配到任何文档。 PUT task1 {"mappings": {"…...
g++ 预处理 编译 汇编 链接 命令
g 预处理 编译 汇编 链接 命令 在命令行中使用 g 预处理、编译、汇编和链接源代码文件通常遵循以下步骤: 预处理(Preprocessing):将源代码文件转换为经过预处理器处理的中间文件。 g -E source.cpp -o source.i 编译ÿ…...
计算机视觉中的low-level与 high-level任务
文章目录 low-level任务high-level任务区别联系others参考在计算机视觉领域中,low-level任务和high-level任务是两个重要的概念,他们分别涉及图像处理和分析的不同的层次。 low-level任务 low-level任务主要关注的是图像的底层特征,如颜色、纹理、边缘、形状等。通常涉及对…...
安徽京准NTP时钟系统:GPS北斗卫星授时下的生活重塑
安徽京准NTP时钟系统:GPS北斗卫星授时下的生活重塑 安徽京准NTP时钟系统:GPS北斗卫星授时下的生活重塑 时间的流逝自古以来时钟都是人类生活与活动的基础。然而,随着科技的进步,我们对时间管理和测量的方法已经发生了翻天覆地的变…...
图论第8天
685.冗余连接II 这题需要考虑两种情况: 1.两个输入 2.没有两个输入就是有成环 class Solution { public:static const int N 1005;int father[N];int n;void init(){for (int i 0; i < n; i){father[i] i;}}int find(int x){return x father[x] ? x : f…...
Python怎么配置环境变量:深度探索与实战指南
Python怎么配置环境变量:深度探索与实战指南 在Python编程的世界中,环境变量的配置是一个至关重要的步骤。它不仅影响着Python解释器的运行,还关系到各种第三方库和工具的使用。本文将带你深度探索如何配置Python的环境变量,并为…...
计网期末复习指南(六):应用层(DNS、FTP、URL、HTTP、SMTP、POP3)
前言:本系列文章旨在通过TCP/IP协议簇自下而上的梳理大致的知识点,从计算机网络体系结构出发到应用层,每一个协议层通过一篇文章进行总结,本系列正在持续更新中... 计网期末复习指南(一):计算…...
HTML做成一个炫酷跳动爱心的页面
大家好,今天制作制作一个炫酷跳动爱心的页面! 先看具体效果: 要创建一个炫酷跳动爱心的HTML页面,你可以使用HTML、CSS和JavaScript的组合。以下是一个简单的示例,它使用CSS动画和JavaScript来实现跳动效果。 首先&…...
React + SpringBoot实现图片预览和视频在线播放,其中视频实现切片保存和分段播放
图片预览和视频在线播放 需求描述 实现播放视频的需求时,往往是前端直接加载一个mp4文件,这样做法在遇到视频文件较大时,容易造成卡顿,不能及时加载出来。我们可以将视频进行切片,然后分段加载。播放一点加载一点&am…...
Suse Linux ssh配置免密后仍需要输入密码
【问题描述】 Suse Linux已经配置了ssh免密,但无法ssh到目标服务器。 对自身的ssh登陆也需要输入密码。 系统–Suse 15 SP5 【重现步骤】 1.使用ssh-keygen -t rsa生产key文件 2.使用ssh-copy-id拷贝public key到目标机器(或者自身) 3.配置成功后ssh 目标时仍需要输…...
apifox 生成签名
目录 前言准备编写签名脚本签名说明捋清思路编码获取签名所需的参数生成签名将签名放到合适的位置完整代码 在apifox中配置脚本新增公共脚本引用公共脚本添加环境变量 参考 前言 略 准备 查看apifox提供的最佳实践文章:接口签名如何处理 编写签名脚本 签名说明…...
介绍建造者模式
建造者模式 将一个复杂对象的创建与它的表示分离,使得同样的构建过程可以创建不同的表示 四种角色 Product 产品角色 指的是一个具体的产品对象Builder 抽象建造者 创建一个产品对象的各个部件的接口/抽象类ConcreteBuilder 具体建造者 实现或继承抽象建造者接口…...
【全部更新完毕】2024全国大学生数据统计与分析竞赛B题思路代码文章教学数学建模-电信银行卡诈骗的数据分析
电信银行卡诈骗的数据分析 摘要 电信银行卡诈骗是当前社会中严重的犯罪问题,分析电信银行卡交易数据,找出高风险交易特征,建立预测模型,将有助于公安部门和金融机构更好地防范诈骗行为,保障用户的财产安全。 针对问…...
【应用浅谈】Odoo的库存计价与产品成本(三)
序言:时间是我们最宝贵的财富,珍惜手上的每个时分 Odoo的库存(Stock)模块拥有众多功能,其中库存计价是一项非常重要的功能,原生的成本方法分三种:【标准成本】,【平均成本】,【先进先出】&#…...
数据结构之ArrayList与顺序表(下)
找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏:数据结构(Java版) 目录 ArrayList的具体使用 118. 杨辉三角 扑克洗牌算法 接上篇:数据结构之ArrayLis…...
openi启智社区 aarch64 npu环境安装飞桨paddlepaddle和PaddleNLP(失败)
以前在启智社区都是编译安装飞桨,这回看到飞桨提供了npu安装包,兴冲冲的以为安装很简单。 之所以安装飞桨,是因为想在启智社区的启智大脑调试环境使用最新的PaddleNLP,结果报错:No module named paddle.nn.layer.laye…...
【漏洞复现】多客圈子论坛系统 httpGet 任意文件读取漏洞
0x01 产品简介 多客圈子论坛系统是一种面向特定人群或特定话题的社交网络,它提供了用户之间交流、分享、讨论的平台。在这个系统中,用户可以创建、加入不同的圈子,圈子可以是基于兴趣、地域、职业等不同主题的。用户可以在圈子中发帖、评论、…...
46-1 护网溯源 - 钓鱼邮件溯源
一、客户提供钓鱼邮件样本 二、行为分析 三、样本分析 对钓鱼邮件中的木马程序1111.exe文件进行了分析,提交了360安全大脑沙箱云和微步在线云沙箱。 360安全大脑沙箱云显示,该1111.exe文件存在危险,因此在解压时需要谨慎操作,以免触发木马程序。 建议使用360压缩软件进行…...
鸿蒙低代码开发一个高频问题
在版本是DevEco Studio 3.1.1 Release,SDK是3.1.0(API9)。 创建和设计的visual文件经常会遇到无法渲染的情况,或者自定义组件在Custom列表中突然不见了的情况。 有以下报错信息的: JSON schema validation error: data/visualModel/value/…...
关于使用南墙waf防护halo网站主页请求404报错的解决方案
文章目录 环境说明问题展示原因探究解决方法 环境说明 在1panel应用商店,部署南墙waf(docker版)halo(2.16.1社区版)注意部署过程中注意uuwaf必须勾选允许外部访问,halo可以不勾选[这里为了证明确实是南墙waf的原因,选择勾选] 问题展示 使…...
Elasticsearch 认证模拟题 - 13
一、题目 集群中有索引 task3,用 oa、OA、Oa、oA 查询结构是 4 条,使用 dingding 的查询结果是 1 条。通过 reindex 索引 task3 为 task3_new,能够使 task3_new 满足以下查询条件。 使用 oa、OA、Oa、oA、0A、dingding 查询都能够返回 6 条…...
Day25 首页待办事项及备忘录添加功能
本章节,完成首页待办事项及备忘录添加功能 一.修改待办事项和备忘录逻辑处理类,即AddMemoViewModel和AddTodoViewModel 在 AddMemoViewModel逻辑处理类中,为了支持与其关联的View视图文件的数据绑定,需要定义一个与视图文件相匹配的实体类 Model。这个Model将包含 View中…...
SpringBoot——全局异常处理
目录 异常 项目总结 新建一个SpringBoot项目 pom.xml Result(通用的响应结果类) MyBusinessException自定义异常类 GlobalExceptionHandler全局异常处理类 ExceptionController控制器 SpringbootExceptionApplication启动类 参考文章:…...
SpringBoot+Vue教师工作量管理系统(前后端分离)
技术栈 JavaSpringBootMavenMySQLMyBatisVueShiroElement-UI 角色对应功能 教师管理员 功能截图...
华为OD技术面试-最长回文串-2024手撕代码真题
题目:最长回文串 给定一个包含大写字母和小写字母的字符串 s ,返回 通过这些字母构造成的 最长的 回文串 的长度。 在构造过程中,请注意 区分大小写 。比如 "Aa" 不能当做一个回文字符串。 示例 1: 输入:s = "abccccdd" 输出:7 解释: 我们可以构造的最…...
Python实现连连看8
4 游戏开始 连连看游戏实际上主要完成的是对玩家鼠标点击事件的处理,也就是对鼠标点击事件的响应。 4.1 添加鼠标点击事件响应 在“1.3.4 在窗口上铺设画布”中提到的将画布pack()到窗口代码之前,写入如下代码,其功能是为鼠标点击事件添加响应。 canvas.bind(<Button…...
[Cloud Networking] Layer Protocol (continue)
文章目录 1. STP / RSTP / MSTP Protocol1.1 STP的作用1.2 STP 生成树算法的三个步骤1.3 STP缺点 2. ARP Protocol3. DHCP Protocol3.1 DHCP 三种分配方式3.2 DHCP 攻击 4. IPSEC / MACSEC 1. STP / RSTP / MSTP Protocol 1.1 STP的作用 消除二层环路:通过阻断冗余…...
重庆网站seo公司/招工 最新招聘信息
1. 账户与账户安全 账户和组是操作系统的基本概念,linux的组有基本组和附加组之分,一个用户只可以加入到一个基本组中国,但是可以加入到多个附加组中.创建用户时,系统默认会自动创建同名的组,并设置用户加入该基本组中. 1.1 创建账户和组 1. useraddm-c 设置账户描述信息,一…...
做网站郑州汉狮/上海城市分站seo
Python3中有六种基本数据类型: Number(数字) String(字符串) List(列表) Tuple(元组) Set(集合) Dict(字典) 他们之前有什么区别?联系?直接上图:按照图示的分类,开始学习吧。(python3) Number(数字类型) Python3 支持 int、float、bool、complex(复数)…...
电子商务网站建设核心是/舆情信息网
1.使用XShell将下载好的jdk-9.0.1_linux-x64_bin.tar.gz包上传到/opt/下 2.解压文件 $ tar -zxvf jdk-9.0.1_linux-x64_bin.tar.gz3.重命名 $ mv jdk-9.0.1 jdk94.打印JAVA_HOME目录 $cd /opt/jdk/jdk9 $pwd /opt/jdk/jdk95.设置环境变量: $ vi /etc/profile #在文件…...
扬中网站建设/登封搜索引擎优化
2019独角兽企业重金招聘Python工程师标准>>> 当你无法迅速的理解一个方法的逻辑时,把方法的逻辑转换成几个同一层面上的、能够说明意图的步骤。 动机: Composed Method由对其他方法的调用组成,好的Composed Method的代码都在细节的…...
网站建设 数据库/谷歌搜索引擎入口2022
项目组成员在针对要开发的系统做需求调研后,就要编写对应的需求说明书。 作为软件工程师,你就得知道需求分析说明书和需求规格说明书的区别,以期在正确的时候编写正确的需求文档。 两者有何不同: (1)面向…...
湖北建设监理协会网站/58同城安居客
转自:http://blog.163.com/fghok_018/blog/static/122599670201072773924530/ 近一个月,宿舍的好多同学都买了笔记本电脑,当然,我也买了,学校的网说实话不稳定,貌似局域网游戏也没办法玩,主要是…...