深入现代 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

SkyWalking - .NET / C++ / Lua 探针现状与社区支持

SkyWalking - .NET / C++ / Lua 探针现状与社区支持

👋 大家好,欢迎来到我的技术博客! 📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。 🎯 本文将围绕SkyWalking这个话题展开,希望能为你带来一些启发或实用的参考。 🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获! 文章目录 * SkyWalking - .NET / C++ / Lua 探针现状与社区支持 🌐 * 一、SkyWalking 多语言探针架构概览 🧩 * 二、Java 探针:成熟稳定,功能最全 ☕️ * 示例:Spring Boot 应用接入 SkyWalking * Java 探针高级特性 * 三、.NET 探针现状:渐趋成熟,生产可用 🖥️ * 技术原理 * 使用方式 * 当前支持的功能 * 局限性 * 四、C++ 探针现状:SDK 形式,适合嵌入式场景 ⚙️ * cpp2sky SDK

By Ne0inhk

C++ 基础语法完全入门指南 - 针对零基础小白

第一部分:C++是什么?为什么学习它? 1.1 C++简介 C++就像是一种与计算机对话的语言,它: * 高效快速:直接操作计算机硬件,运行速度快 * 功能强大:可以用来开发游戏、操作系统、科学计算等 * 学习曲线:开始有点难,但掌握后非常强大 1.2 第一个C++程序 - “Hello World” #include<iostream>// 包含输入输出库intmain(){// 主函数,程序从这里开始执行 std::cout <<"Hello, World!"<< std::endl;// 输出文字到屏幕return0;// 程序正常结束} 逐行解释:

By Ne0inhk
Qt Creator 18.0.2 (macOS, Linux, Windows) - Qt、QML 与 C++ 的 跨平台 IDE

Qt Creator 18.0.2 (macOS, Linux, Windows) - Qt、QML 与 C++ 的 跨平台 IDE

Qt Creator 18.0.2 (macOS, Linux, Windows) - Qt、QML 与 C++ 的 跨平台 IDE cross-platform, integrated development environment (IDE) for application developers to create applications for multiple desktop, embedded, and mobile device platforms. 请访问原文链接:https://sysin.org/blog/qt-creator/ 查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org Qt Creator IDE:

By Ne0inhk
【Java毕设源码分享】基于springboot+vue的露营地管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【Java毕设源码分享】基于springboot+vue的露营地管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围::小程序、SpringBoot、SSM、JSP、Vue、PHP、Java、python、爬虫、数据可视化、大数据、物联网、机器学习等设计与开发。 主要内容:免费开题报告、任务书、全bao定制+中期检查PPT、代码编写、🚢文编写和辅导、🚢文降重、长期答辩答疑辅导、一对一专业代码讲解辅导答辩、模拟答辩演练、和理解代码逻辑思路。 🍅文末获取源码🍅 感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及🚢文编写等相关问题都可以给我留言咨询,希望帮助更多的人 文章目录 * 演示视频 * 系统功能 * 具体实现部分截图 * 架构设计

By Ne0inhk