C++ 中的枚举类型

Jinku Hu 2023年1月30日 2021年6月28日
  1. C++ 中的无作用域枚举
  2. C++ 中的作用域枚举
C++ 中的枚举类型

本文将演示如何在 C++ 中使用枚举类型。

C++ 中的无作用域枚举

一段时间以来,枚举一直是 C 语言的一部分。C++ 还通过一些附加功能实现了相同的概念。通常,枚举是命名常量整数的机制。程序员定义枚举器名称。整数值可以明确指定或通过给定名称的位置推断。

枚举是使用关键字 enum 确定的,它们可以选择定义类型的名称(例如,以下代码片段中的 Color)。请注意,C++ 枚举常量具有实现定义的整数类型。因此,如果给定值需要比 int 更大的空间,则选择相应的整数类型作为基础类型。类型也可以由用户在枚举名称后显式指定,需要用单个冒号分隔(如本文第四个代码段所示)。

在下面的示例中,我们定义了一个名为 Color 的枚举,并将六种颜色名称指定为枚举常量。由于这些常量都没有分配给它们的显式值,因此积分值是从它们的位置从零开始推导出来的。这段代码实现了一个颜色到字符串的转换函数,它仅限于给定的值。变量 Color 也是一个无作用域的枚举;这意味着它的枚举器(常量)可以从与枚举本身相同的范围访问。

#include <iostream>

using std::cout;
using std::endl;
using std::string;

enum Color { RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW };

string ColorToString(Color c) {
    switch(c) {
        case RED: return "Red";
        case BLUE: return "Blue";
        case GREEN: return "Green";
        case CYAN: return "Cyan";
        case MAGENTA: return "Magenta";
        case YELLOW: return "Yellow";
        default: return "NAN";
    }
}

int main() {
    Color col1 = RED;

    cout << "the given color is " << ColorToString(col1) << endl;

    return EXIT_SUCCESS;
}

输出:

the given color is Red

或者,我们可以定义一个枚举(例如 WeekDay),其中每个枚举器都具有明确分配的整数值。你可以利用此功能来实现可以根据不同日期约定进行修改的灵活结构。如果需要,可以在同一个枚举对象中混合显式值和位置值。

#include <iostream>

using std::cout;
using std::endl;

enum WeekDay { MON = 1, TUE = 2, WED = 3, THU = 4,
            FRI = 5 , SAT = 6, SUN = 7 };

int main() {
    auto today = SAT;
    cout << "today is " << today << "th day" << endl;

    return EXIT_SUCCESS;
}

输出:

today is 6th day

C++ 中的作用域枚举

枚举的另一个有用的特性是有一个作用域;因此,它被称为作用域枚举。后一个可以使用 enum classenum struct 关键字声明。作用域枚举遵循通常的作用域约定,并且不能在枚举作用域之外访问。从好的方面来说,全局范围的枚举不会像非范围的枚举那样导致名称冲突。

下一个代码示例将上一个示例中的 WeekDay 定义为作用域枚举。请注意,可以使用 cout 函数作为任何其他变量来打印无作用域枚举,但需要将作用域枚举转换为相应的整数值。

#include <iostream>

using std::cout;
using std::endl;

enum class WeekDay { MON = -1, TUE = 2, WED = 3, THU = 4,
    FRI = 5 , SAT = 6, SUN = 7 };

int main() {
    auto today = WeekDay::MON;
    cout << "today is " << static_cast<unsigned>(today) << "th day" << endl;

    return EXIT_SUCCESS;
}

输出:

today is 6th day

与无作用域的枚举相比,有作用域的枚举必须有一个名称。另一方面,作用域枚举没有默认的底层整数类型。请注意,将枚举数强制转换为不同类型时,底层类型转换可能会导致溢出。

#include <iostream>

using std::cout;
using std::endl;

enum class WeekDay : int { MON = -1, TUE = 2, WED = 3, THU = 4,
    FRI = 5 , SAT = 6, SUN = 7 };

int main() {
    auto today = WeekDay::MON;
    cout << "today is " << static_cast<unsigned>(today) << "th day" << endl;

    return EXIT_SUCCESS;
}

输出:

today is 4294967295th day
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相关文章 - C++ Enum