020 - C++ 枚举

news2024/12/23 22:42:35

今天我们要讲的是 C++ 中的枚举。

enum 是 enumeration 的缩写,基本上可以说,它就是一个数值集合。如果你想要给枚举一个更实际的定义,它们是给一个值命名的一种方法。

所以我们不用一堆叫做 A、B、C 的整数。我们可以有一个枚举数。它的值是A、B、C。它们与整数相对应。这能帮助我们将一维数值集合作为类型,而不仅仅是用整型作为类型。

当然你可以给它赋值任何整数,也就是设置哪些值可以赋值。

枚举其实一点都不复杂,就是这些了。它只是一种命名值的方法,当你想要使用整数来表示某些状态或者某些数值时,它非常有用。

通俗的来讲,你希望为一些值指定一个名称,以便代码更易于阅读。所以不管怎么说枚举数其实就是一个整数。能让你的代码持干净一点。

然而在你实际的代码中,看起来可能和你想的有点不一样。

为什么使用枚举

让我们来看看具体的看例子吧。

i537e8.png

我有三个值要处理。我们把 A 设为 0,B 设为1,C 设为 2。然后在 main 的某个地方使用 value 变量。先让它等于这三个中的一个,然后通过一些代码来检查当前的 value 值是什么,然后执行某种操作。

很好,然而这样会带来一些问题。

这些 ABC 根本就没有分组,在代码后面的某个地方,你可能会有一个 D,或者你可能想再次声明 A,这就成了一个问题。——本质上最大的问题还是这些变量根本没有分组。

此外,它们只是整数。

这也就意味着我可以在将 value 值的直接赋值为 5,那它下面的代码就没有意义了。

我们希望能够从本质上定义一个类型,它只能是这三个数中的一种,而且能够把它们组合起来。——这里正是我们使用枚举的地方。

如何使用枚举

我们对代码做一些修改。

我创建一个枚举 enum。叫作 Example,然后我可以列出我想要的值。例如 A、B 或 C。这里不用 int 作为类型了。

现在我们可以使用枚举的名称作为实际类型。

下面的代码可以这样写。(注意:我把之前的变量改为小写)

i53EaZ.png

这样就可以正确的使用枚举了。我们可以像例子中那样赋值。

如果我尝试赋别的值,会得到一个错误。——因为它必须是上面三个中的一个。

i53zkF.png

而且你要记住一点。这里面的值只能是整数

好了,接下来可以做之前想做的操作了。比如我会这样写。

i536BH.png

你这个时候会有一个疑问。——我怎么知道 B 的值是多少?

你把鼠标悬停在第五行,查看 ABC 的值。可以清楚的看到 A 的值是 0,B 的值是 1,C 的值是 2。这些值是默认的,它默认第一个是 0,然后它一个接一个的递增。

你也可以直接指定它们的值,你想要设置成多少都可以。

i53F9Q.png

如果你从一个非 0 的数字开始(比如 5),没有指定其余的值,你可以看到后面的 B 的值变为了6,C的值是7。就是这样递增的。

这里还可以做的另外一件事,是指定你想要给枚举赋值的整数类型。

i53dAE.png

这样做的的作用是:设置每一个数据的类型是 8 位整型。默认是 32 位的整型,——其实没有必要用那么大的数字是吧。

所以这样做减少了内存的使用。

不过千万要记住,这里不能使用 float。float 不是整数,这里必须是一个整数,比如char。

这就是枚举的本质,它只是给特定的值命名的一种方式。然后你就不必在各种地方处理各种整数了。

真正实用的例子

让我们来看一个真正的例子,你可能会在这里使用枚举。

我们有一个日志类,这个类在 如何写一个 C++ 类 那一期讲过。

我们先简单的回顾一下那个程序。

i53hrC.png

在这里我们使用了三个不同的 log 级别。它们只是整数 0、1、2。可以看到这是一个非常适合用枚举的地方。

因为我们有三个值,我们用它们作为整数来表示某个状态。

这个例子中的日志级别是指会展示哪种级别的日志。

接下来我们在这个类中创建一个名叫 Level 的枚举。

i535hP.png

你可以看到我显示的把这个 Error、Warning、Info 设置为 0、1、2。我个人很喜欢这样做,这样可以帮助代码提高可读性。

然后删除下面的几个定义,最后调整成现在这个样子。

我们将它设置为枚举,等于是加了条件,它只能是那三个值了(纯粹从语法上 C++ 编译器会强制执行这些限制,但你也可以很容易的绕过它。它不是那种从物理上都无法设定的东西)。当然,我们的枚举数只是四字节的整数,只有四个字节的内存,你可以可以把任何你想要的东西放进那个内存里。

ok,我们通过设置类型为 Level 来限制我们的代码。

将下面的代码也做一些修正。

i53oZX.png

然后是主程序当中的 SetLevel 函数。

i53sOt.png

你会发现这里的设置有点不太一样。我们有一个枚举数叫做 Warning。在 Log 这个类的命名空间中,这个枚举 Level 本身不是一个命名空间,这个叫做枚举类,本期先不做介绍,我们会在之后的系列中讲到。

然而,对于普通的枚举而言,Level 并不是真正的命名空间,所以你不能把它当成一个命名空间,就意味着 Warning 和 Info 它们只存在于这个日志类中。你看到我可以把它设置为 Warning。

现在程序一切正常了。

如果你实际尝试过,可能已经注意到 Error 实际上并不起作用,设置成 Error 会报错。

之所以会这样。是因为我们还有一个叫做 Error 的函数。没错,相同的名字。这是我特意设置的,是为了告诉你们如果名字有冲突会发生什么。

我们尝试引用像 Error 这样的东西时,它不知道指的是函数。所以这里绝对不能其他一个叫做 Error 的东西。

如果我们想要一个同名的函数,我建议你在枚举数之前加上 Level 前缀。

顺便说一下,这是很常见的做法,这样我们就知道我们指的是什么。

我们把下面能改的地方都改一下。运行代码你会发现没有什么问题的。

最后的话

好了,枚举的本质就是让我们的编码更容易,让我们的代码更干净。

在枚举的后面其实就是整数,你可以把它们用在很多地方。枚举有很多很多用途,我们将在以后的细节中介绍(有可能还会有一个专门介绍枚举类的一期)。

好了,记住:如果你有一个数值集合想要用数字来表示它们,那么枚举就是你想要的。

本期就是这些,喜欢的小伙伴可以点点赞哦。下期再见。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flask 与 Django 先学哪个呢

本文把 Flask 和 Django 做一个比对,因为我对这两个 Python Web 框架都有实际的开发经验。希望我可以帮助您选择学习哪个框架,因为学习一个框架可能会非常耗时 —— 当然也很有趣! 相似之处 让我们从相似之处开始。 No. 1 Flask 和 Djang…

ROS学习第二十七节——URDF集成Rviz基本流程

前面介绍过,URDF 不能单独使用,需要结合 Rviz 或 Gazebo,URDF 只是一个文件,需要在 Rviz 或 Gazebo 中渲染成图形化的机器人模型,当前,首先演示URDF与Rviz的集成使用,因为URDF与Rviz的集成较之于…

ROS学习第二十八节——URDF之robot link

1.概述 URDF 文件是一个标准的 XML 文件,在 ROS 中预定义了一系列的标签用于描述机器人模型,机器人模型可能较为复杂,但是 ROS 的 URDF 中机器人的组成却是较为简单,可以主要简化为两部分:连杆(link标签) 与 关节(joint标签)&…

数据库基础篇 《11.数据处理之增删改》

1. 插入数据 1.1 实际问题 解决方式:使用 INSERT 语句向表中插入数据。 1.2 方式1:VALUES的方式添加 使用这种语法一次只能向表中插入一条数据。 情况1:为表的所有字段按默认顺序插入数据 INSERT INTO 表名 VALUES (value1,value2,....);…

03.初始React脚手架

一.使用create-react-app创建react应用 1.react脚手架 xxx脚手架:用来帮助程序员快速创建一个基于xxx库的模板项目 包含了所有需要的配置(语法检查,jsx编译,devServer…)下载好了所有相关的依赖可以直接运行一个简单…

硬件还不够!激光雷达「开卷」感知算法+数据闭环

激光雷达正式进入量产周期,而如何用好激光雷达,并形成更优更具性价比的激光雷达系统方案,助力激光雷达量产上车并真正用好激光雷达系统,将是接下来两年激光雷达赛道的主要方向。 在近期开幕的上海国际车展上,亮道智能…

学系统集成项目管理工程师(中项)系列10_立项管理

1. 系统集成项目管理至关重要的一个环节 2. 重点在于是否要启动一个项目,并为其提供相应的预算支持 3. 项目建议 3.1. Request for Proposal, RFP 3.2. 立项申请 3.3. 项目建设单位向上级主管部门提交的项目申请文件,是对拟建项目提出的总体设想 3…

延迟渲染 Deferred Rendering

前向渲染 先计算光照再裁剪。 前向渲染是现在最基础,也是最多引擎使用的标准。前向渲染的流程是给定一个几何体,引擎对其进行从顶点到像素着色器的一系列计算,然后输出到最终的图像缓冲区。场景中有多个几何体时,引擎就是对其挨个…

薪资18K需要什么水平?来看看98年测试工程师的面试全过程…

我的情况 大概介绍一下个人情况,男,本科,三年多测试工作经验,懂python,会写脚本,会selenium,会性能,然而到今天都没有收到一份offer!从年后就开始准备简历,年…

西交大-一百本书-解决不能粘贴的限制

快毕业了,要填四个一百,其他三个都几分钟就填完了。只有读一百本书要写读书笔记且不能粘贴,防谁呢真是的。发现一种解决不能粘贴限制的方法。顺道附上利用ChatGpt快速生成书评的方法。 四个一百网址 一、 解除粘贴限制 以edge浏览器为例 登…

Python|勘测定界TXT坐标点转shp文件——Arcpy实现

平时日常工作中,经常会遇到txt格式的测绘数据,这类数据通常只有不同地块的界址点集和坐标系信息,没法直接导入GIS软件中进行分析。拿到这类原始文本文件,首要工作就是将之转换为shp图层数据。 今天,主要分享两种转shp数据的方法,一种是在arcmap中直接转换,另一种是通过…

springboot+RateLimiter+AOP自定义注解限流

springbootRateLimiterAOP自定义注解限流 RateLimiter简介springboot集成RateLimiterpom.xml引入RateLimiter常用api代码实现自定义注解Limiter限流切面验证 RateLimiter简介 RateLimiter是Guava库中的一个限流器,它提供如下功能: (1)基于PPS进行限流 (…

论文推荐:基于联合损失函数的多任务肿瘤分割

以FFANet为主干,加入分类的分支,将模型扩展为多任务图像分割框架,设计了用于分类和分割的联合损失函数。 FFANetMTL 1、FFANet和分割分支 FFANet作为骨干网络,作为对VoVNet的重新设计和优化,FFANet在骨干网中加入了残…

SpringMVC请求与响应

文章目录 请求与响应请求映射路径请求传参传递普通参数传递实体类参数传递数组参数传递集合参数传递JSON参数传递日期参数 响应数据 请求与响应 请求映射路径 请求映射路径是通过注解: RequestMapping 类型:方法注解, 类注解 位置:SpringMVC控制器方法…

少儿编程 中国电子学会图形化编程等级考试Scratch编程一级真题解析(判断题)2023年3月

2023年3月scratch编程等级考试一级真题 判断题(共10题,每题2分,共20分) 26、在角色列表区和造型标签页都可以修改角色的名称。 答案:错 考点分析:考查Scratch平台使用,只有角色区可以修改角色的造型名称,造型标签不能修改,所以答案错误 27、可以在角色中切换舞台的…

Java核心技术 卷1-总结-7

Java核心技术 卷1-总结-7 lambda 表达式方法引用构造器引用变量作用域异常分类声明受查异常 lambda 表达式 方法引用 有时, 可能已经有现成的方法可以完成你想要传递到其他代码的某个动作。例如, 假设你希望只要出现一个定时器事件就打印这个事件对象。…

使用@Scope注解设置组件的作用域

前言 Spring容器中的组件默认是单例的,在Spring启动时就会实例化并初始化这些对象,并将其放到Spring容器中,之后,每次获取对象时,直接从Spring容器中获取,而不再创建对象。 1.Scope注解概述 Scope注解能…

【uni-app】【01】底部导航栏与页面切换

1.(配置文件在哪)uni-app 路由控制是在 pages.json文件中的。 2.(基本配置项有哪些)初学的时候主要有三个配置项,①pages ② globalStyle ③ tabbar [!TOC] 接下来主要是对这三个配置项做一个简单介绍。 pages 负责页面管理。不需要自己写的,你在项目的p…

【Scala入门】scala基础语法:类和对象,变量和常量

上一篇请移步【Scala入门】Scala下载及安装(Windows)以及Idea创建第一个scala项目_水w的博客-CSDN博客 目录 一、Scala 二、Scala基础语法 2.1 注释与标识符规范 2.2 变量与常量 【案例:变量声明和赋值】 2.3 object 【案例&#xff1…

合并二叉树-递归法

1题目 给你两棵二叉树: root1 和 root2 。 想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠…