C++中的enum(枚举)是什么,以及与C中enum的不同之处

最近在看《A Tour of C++ 3rd》的时候发现 C 和 C++ 的 enum虽然使用起来比较相似,但是目的却略有不同。关于枚举的概念还请见之前写过一篇关于 C 的那篇博客《C语言中enum(枚举)详解》,这里不再赘述。本文侧重 C++ 与 C 不同的地方。

首先,默认情况下与 C 一样,值的类型为整数,所以下面样式的代码依旧可以使用:

#include <iostream>

enum {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};

int main()
{
    int x1 = Jan;
    std::cout<<x1<<std::endl;
}

C++ 不同版本的枚举使用方法也有所不同,但是上面这种“plain”版本的都是一样的。所以本文不会详细介绍 C++11 到 C++23 每个版本的使用方法,主要是介绍概念(因为这个概念我花了一段时间才搞明白)。

但是《A Tour of C++ 3rd》和《The C Programming Language》这两本书对于枚举的目的描述却不太一样。

在《The C Programming Language》中,enum被描述成一种“常量列表”;但是在《A Tour of C++ 3rd》中,enum则被描述成一种用户定义类型的简单方式,相比 C 的enum扩充了一些功能。

C++11 添加了作用域内枚举enum class,有时候枚举可能会重名,这样就可以解决重名的问题了。如下:

enum class Color { red, blue, green };
enum class Light { red, blue, green };

要牢记enum class是一个整体,含义是创建一个class一样的枚举,也就是说class后面的是一个自定义的类型,而大括号内的是这个“类”的域

当我们要使用上面Color中的red时,需要按照表示red所属的是哪个enum class

std::cout<<int(Color::red);
//OutPut:0

这里将Color转换成基础数据类型,会发现也还是0。但是需要注意,这里依旧和 C 中一样,Color::red表示的是Colorred, blue, green三者中的red这个常量,并不是类或结构体中的成员变量,这是非常容易混淆的一点

如果使用了enum class,虽然可以赋值、初始化、比较,但是就不能像 C 那样简单地输出这些枚举常量了,需要将其转换成基础数据类型(默认为整数)或者自己写输出功能。但是我们可以用enum class创建的类型来创建新的常量:

Color x = Color::red;
std::cout<<int(x);
//OutPut:0

这里的x会被认为和Color::red是一类的,二者可以比较,如下:

if (x == Color::red) {
	std::cout<<"x等于Color::red";    
}
//x等于Color::red

如果你看了我 C 的那一篇博客的话,最后提到枚举的一个用途就是对比(比如作为if的判断部分)。所以 C++ 默认支持的三个功能之一就是比较。而且我们可以指定值来创建常量,方法如下(二者等价,但是不同版本 C++ 可能会不同):

Color x = Color(10);	//C++11及更新版本
Color x {10};			//C++17及更新版本

这样x就是和Color::red是一个类型的常量,二者可以互相比较,但值为10。这种方法虽然变得复杂了一些,但可以比较灵活地实现一些情况的判断。

书中给出了一个红绿灯的例子挺有意思的。(下面我修改了一些地方,不是书中的,但是思路一样)。

首先重载++x操作符:

Color& operator++(Color& c)
{
    using enum Color;	//这个要C++20
    
    switch (c) {
        case red:   return c=blue;
        case blue:   return c=green;
        case green:   return c=red;
    }
}

然后就可以通过++x获取到枚举列表的下一个元素:

Color x = Color::red;
std::cout<<int(x)<<std::endl;
std::cout<<int(++x)<<std::endl;

希望能帮到有需要的人~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值