深入现代 C++:enum class 全面解析,彻底告别枚举踩坑!

深入现代 C++:enum class 全面解析,彻底告别枚举踩坑!

本篇摘要

  • 在 C++11 中引入了 枚举类(enum class),它是对传统 enum 的现代化改进,解决了传统枚举的多个问题,如命名冲突、隐式类型转换、作用域污染等。
在这里插入图片描述

一·传统枚举

如:

enumColor{ RED, GREEN, BLUE };enumLight{ RED,// 编译错误!命名冲突 YELLOW };
  • 我们会发现枚举的成员有冲突,因此会导致下面编译的报错:
在这里插入图片描述

传统 enum 存在的问题:

  • 命名冲突:不同枚举之间不能有相同的名字:

就是这个例子:

在这里插入图片描述
  • 作用域污染:枚举值暴露在全局或当前命名空间:

比如这里我们可以直接通过外接访问到这个成员:

在这里插入图片描述
  • 隐式转换:枚举值可以自动转换为 int
在这里插入图片描述

下面我们运行下:

root@hcss-ecs-7d13:/home/sw/linux_learn/extra_knowledge/enum_class# ./a.out0

发现结果就是0,明显自动隐式转换了。

  • 安全性差:容易误用、类型不安全。

这里就是我们上面暴露的问题的总结了,因此下面我们引入了C++的枚举类!

二·C++的枚举类

首先总结下它的特点,也就是对上面缺点的修正:

特性说明
作用域隔离枚举值只能通过 枚举类名::值 访问
类型安全不允许隐式转换为 int
可指定底层类型可控制枚举值的存储大小
可读性高代码结构清晰,易于维护

具体用法剖析

一般形式(当然我们一般默认成员都显转int,因此底层类型一般不写):

enumclass 枚举类名 [: 底层类型]{ 枚举值1, 枚举值2,...};

简单使用

比如还是那上面我们那个例子说明:

enumclassColor{ Red, Green, Blue };enumclassLight:uint32_t{ Red, Yellow };
  • 此时再编译就不会报错了!

此时我们需要突破类域方式去访问了:

在这里插入图片描述

运行结果:

root@hcss-ecs-7d13:/home/sw/linux_learn/extra_knowledge/enum_class# ./a.out Color is Red 

枚举类的底层类型Underlying Type

enumclassColor:uint8_t{ Red, Green, Blue };
  • 每个成员8个比特,理论这个枚举类大小就是1字节,下面验证下:

sizeof(Color) 后结果:

在这里插入图片描述

常见底层类型:

  • int(默认)
  • uint8_t / int8_t
  • uint16_t / int16_t
  • uint32_t / int32_t
  • uint64_t / int64_t

枚举类与整数的转换

由于 enum class 不允许隐式转换,必须显式转换。

只能:

static_cast<int>(c);

下面来验证下:

enumclassColor:uint8_t{ Red, Green, Blue };
Color c = Color::Green;int value =static_cast<int>(c); std::cout << value << std::endl;

结果符合预期:

在这里插入图片描述

但是要是反过来呢?

Color c2 =static_cast<Color>(2);
  • 不建议这样使用,如果整数不在枚举范围内,行为是未定义的。

最后一个特点就明显不用说了吧!

枚举类作为函数参数和返回值

作为函数参数

voidsetColor(Color c){ std::cout <<"Setting color to: "<<static_cast<int>(c)<< std::endl;}

输出:

在这里插入图片描述

作为函数返回值

Color getFavoriteColor(){return Color::Blue;}

这里如果我们强转成对应的类型uint8_t 此时就是这样:

 std::cout<<static_cast<uint8_t>(favorite)<<std::endl;

结果:

在这里插入图片描述
  • 我们发现它是空白其实,因为这杯cout把2转义成char类型,也就是整数2对应的ASIIC码: STX(Start of Text),它是不可见的,所以我们打印出来看不到!

因此需要:

 std::cout<<static_cast<int>(favorite)<<std::endl;

就如下:

在这里插入图片描述

拓展使用

结合switch进行转义选择使用

也就是我们通过对枚举成员进行switch操作,对指定枚举量安排指定操作(其他操作功能可自行拓展):

简单版如下:

enumclassColor:uint8_t{ Red, Green, Blue };voidprintColor(Color c){switch(c){case Color::Red: std::cout <<"Color: Red\n";break;case Color::Green: std::cout <<"Color: Green\n";break;case Color::Blue: std::cout <<"Color: Blue\n";break;default: std::cout <<"Unknown color\n";}}

下面我们测试一下:

在这里插入图片描述

获取枚举类的底层类型

  • 使用 <type_traits> 中的 std::underlying_type 可以获取枚举类的底层类型。

下面我们测试下:

代码:

#include<iostream>#include<type_traits>enumclassLevelType:uint16_t{ UNKNOW =0, DEBUG, INFO, WARN, ERROR };intmain(){using underlying_type = std::underlying_type<LevelType>::type; std::cout <<"Underlying type size: "<<sizeof(underlying_type)<<" bytes\n";return0;}

结果如下:

在这里插入图片描述
  • 符合预期!

封装枚举类:添加描述和状态码

  • 虽然 enum class 提供了类型安全和作用域隔离的优势,但它本身不支持直接附加描述信息或状态码。因此,我们常常需要通过类封装的方式,为枚举类添加描述、状态码、转换函数等功能。

首先要知道和之前的普通枚举一样是可以类内自己给值的:

enumclassCode{ OK=200, NotFound=404, InternalServerError=500};

但是下面我们通过封装类及提供接口方式来完成对应的设置获取等:

基于上述测试代码:

#include<iostream>#include<string>classHttpStatus{public:enumclassCode{ OK, NotFound, InternalServerError };explicitHttpStatus(Code code):code_(code){}// 获取状态码数值intgetStatusCode()const{switch(code_){case Code::OK:return200;case Code::NotFound:return404;case Code::InternalServerError:return500;}return-1;// 不应到达}// 获取状态描述 std::string getDescription()const{switch(code_){case Code::OK:return"OK";case Code::NotFound:return"Not Found";case Code::InternalServerError:return"Internal Server Error";}return"Unknown Status";}// 打印状态信息voidprint()const{ std::cout <<getStatusCode()<<" "<<getDescription()<< std::endl;}private: Code code_;};intmain(){ HttpStatus ok(HttpStatus::Code::OK); HttpStatus notFound(HttpStatus::Code::NotFound); HttpStatus serverError(HttpStatus::Code::InternalServerError); ok.print(); notFound.print(); serverError.print();return0;}
  • 运行后可以发现:
在这里插入图片描述
  • 这里就是我们通过对应的枚举成员码通过Switch进行对应的数字和描述的选择(也是常用作对应的比如http等)

通过类封装,我们可以为枚举类添加描述、状态码、转换方法等高级功能,同时在 switch 中显式处理所有枚举值,确保逻辑完整性和代码健壮性。

总结

一句话:

C++ 枚举类(enum class)是现代 C++ 编程中推荐使用的枚举形式,它解决了传统枚举的诸多问题,提高了代码的安全性、可读性和可维护性。

下面博主准备了关于它使用的顺口溜,帮助大家记忆:

枚举类,C++11,命名不冲突,作用域严。enum class 加限定,Red要加Color::才安全。隐式转换不允许,int转它要static_cast显。底层类型可指定,uint8_t省空间,嵌入式欢。switch要全覆盖,case别漏防出错,default保平安。封装功能更强大,加描述、状态码,类来管。类型安全最重要,enum class替旧版,代码稳!

传统枚举与枚举类对比:

特性传统 enum枚举类 enum class
命名冲突容易发生不会发生(作用域隔离)
隐式转换允许不允许
作用域枚举值暴露在外部枚举值只在类内部可见
可读性较差更清晰、更安全
底层类型不可指定支持指定(如 int, char

可视化流程图:

在这里插入图片描述

本篇分享枚举类使用知识到这里,欢迎大家继续订阅本专栏学习更多知识来充实大脑。

Read more

【AI赋能】MCP+Skill能力下的前端JS逆向自动化落地(附工具)

【AI赋能】MCP+Skill能力下的前端JS逆向自动化落地(附工具)

项目地址 https://github.com/Fausto-404/js-reverse-automation--skill js-reverse-automation--skill 结合chrome-devtools-mcp的能力并加上Skill的规范,实现JSRPC+Flask+autoDecoder方案的前端JS逆向自动化分析,提升JS逆向的效率 适用场景 * 需要快速落地前端签名/加密参数逆向 * 需要将js逆向逻辑封装为可复用的代码 * 需要与 Burp 配合进行抓包、改包 流程设计思路 针对js逆向中常用的远程调用法进行js逆向(如JSRPC+Mitmproxy、JSRPC+Flask等)中,初始配置阶段中面对的定位加密函数、编写注册代码、编写python代码等繁琐操作,通过引入AI的MCP和Skill技术进行赋能,让AI自动完成函数发现与注册代码生成,最终实现从“半自动”到“高自动”的跨越,人员全程只需下方指令,并最终配置一下burp即可完成JS逆向的全流程。 核心能力 * 基于 MCP 连接真实浏览器,触发并跟踪js加密/签名链路

By Ne0inhk

使用Docker安装Ollama及Open-WebUI完整教程

作者:吴业亮 博客:wuyeliang.blog.ZEEKLOG.net 一、Ollama 简介及工作原理 1. Ollama 简介及原理 * 简介:Ollama 是一款轻量级、开源的大语言模型(LLM)运行工具,旨在简化本地部署和运行大语言模型的流程。它支持 Llama 3、Mistral、Gemini 等主流开源模型,用户无需复杂配置即可在本地设备(CPU 或 GPU)上快速启动模型,适用于开发测试、本地智能应用搭建等场景。 * 工作原理: * 采用模型封装机制,将大语言模型的运行环境、依赖库及推理逻辑打包为标准化格式,实现模型的一键下载、启动和版本管理。 * 通过优化的推理引擎适配硬件架构,支持 CPU 基础运行和 GPU 加速(如 NVIDIA CUDA),减少资源占用并提升响应速度。 * 提供简洁的

By Ne0inhk
Flutter 三方库 flutter_dropzone 的鸿蒙化适配指南 - 掌握万物皆可拖拽的资源流转技术、助力鸿蒙大屏与 Web 应用构建极致直观的文件导入与交互体系

Flutter 三方库 flutter_dropzone 的鸿蒙化适配指南 - 掌握万物皆可拖拽的资源流转技术、助力鸿蒙大屏与 Web 应用构建极致直观的文件导入与交互体系

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 flutter_dropzone 的鸿蒙化适配指南 - 掌握万物皆可拖拽的资源流转技术、助力鸿蒙大屏与 Web 应用构建极致直观的文件导入与交互体系 前言 在 OpenHarmony 鸿蒙应用全场景覆盖、特别是适配鸿蒙桌面模式(Desktop Mode)、折叠屏大屏交互及鸿蒙 Web 版推送的工程实战中,“文件拖拽(Drag and Drop)”已成为提升生产力效率的标配功能。用户希望能够像在 PC 上一样,直接将图片或文档拖入应用窗口即可完成上传。如何实现这种跨越边界的直观交互?flutter_dropzone 作为一个专注于“拖放区域感知与文件流提取”的库,旨在为鸿蒙开发者提供一套标准的拖放治理方案。本文将详述其在鸿蒙端的实战技法。 一、原原理分析 / 概念介绍 1.1 基础原理 flutter_dropzone

By Ne0inhk
【前端小站】CSS 样式美学:从基础语法到界面精筑的实战宝典

【前端小站】CSS 样式美学:从基础语法到界面精筑的实战宝典

半桔:个人主页  🔥 个人专栏: 《前端扫盲》《手撕面试算法》《C++从入门到入土》 🔖阻止了我的脚步的,并不是我所看见的东西,而是我所无法看见的那些东西。 《海上钢琴师》 文章目录 * 前言 * 一. CSS是什么 * 1.1 概念 * 1.2 基本语法 * 二. CSS如何引入HTML * 2.1 内部样式表 * 2.2 行内选择器 * 2.3 外部引入 * 三. CSS选择器 * 3.1 基础选择器 * 3.1.1 标签选择器 * 3.1.2 类选择器 * 3.1.3 id选择器 * 3.

By Ne0inhk