C++中的Enum Class详解

发布时间:2023-05-19

一、Enum Class概述

Enum Class(又称Scoped Enumeration,枚举类)是C中用于声明枚举类型的一种方式。与传统的C枚举类型相比,Enum Class提供了更严谨的类型检查、更好的可读性和更佳的作用域管理。

二、Enum Class的定义与使用

Enum Class与普通枚举类型不同,它们必须被显式地定义为一个class或struct的成员,并且默认的枚举类型是int。

enum class Color {
   RED, BLUE, GREEN
};

上面的代码定义了一个名为Color的枚举类,其中包含了三个元素:RED、BLUE和GREEN。在枚举类型被定义之后,就可以用它来声明变量:

Color c = Color::RED;
if (c == Color::RED) {
    cout << "The color is RED" << endl;
}

三、作用域管理与类型检查

与普通枚举类型相比,Enum Class提供了更良好的作用域管理。声明一个Enum Class后,其中的元素都在该Enum Class的命名空间下:

enum class Color {
   RED, BLUE, GREEN
};
enum class Size {
   SMALL, MEDIUM, LARGE
};
int main() {
    Color c = Color::RED;
    Size s = Size::LARGE;
    // c == Size::LARGE;  //编译错误:错误的枚举类型
    return 0;
}

在上面的代码中,Color和Size对元素RED都有定义。但是在main函数中,我们可以安全地使用Color::RED或Size::LARGE,不会发生冲突。如果试图将Color类型与Size类型混淆,则编译器会指出错误。 此外,Enum Class还提供了更严谨的类型检查。这意味着我们无法使用某个Enum Class类型来表示另一个类型:

enum class Color {
   RED, BLUE, GREEN
};
int main() {
    Color c = Color::RED;
    // 以下语句是非法的
    // int n = static_cast<int>(c);
    // int m = c;
    return 0;
}

在上面的代码中,我们试图将Color类型转换为int类型或直接赋值给int类型。由于类型不匹配,编译器将不会通过这样的语句。 如果必须要将Enum Class类型强制转换,可以使用static_cast:

enum class Color {
   RED, BLUE, GREEN
};
int main() {
    Color c = Color::RED;
    int n = static_cast<int>(c);
    return 0;
}

四、Enum Class的默认值

与传统的枚举类型相同,Enum Class的元素也有默认值。不过,与普通枚举类型不同的是,Enum Class的默认值可以在定义时指定。如果未指定,则默认的值为0。注意,即便设置了默认值,Enum Class元素也不能隐式地转换为整数类型,因此它们不能用作数组的索引值或函数参数。

enum class Color {
   RED = 1, BLUE, GREEN
};
int main() {
    Color c = Color::BLUE;
    cout << static_cast<int>(c) << endl; // 输出值为 2
    return 0;
}

五、Enum Class的嵌套和前置声明

Enum Class可以在其他class、namespace或函数中嵌套使用。 在嵌套时,需要使用作用域运算符来引用Elements。同时需要注意,在枚举类定义前声明变量时,需要在该变量名之前加上枚举类名及作用域运算符。

class A {
public:
    enum class Color {
        RED, BLUE, GREEN
    };
    Color c;
};
int main() {
    A::Color c = A::Color::RED;
    return 0;
}

六、Enum Class的强类型枚举

在C++20中,Enum Class提供了一种新的枚举类型,即强类型枚举类型(常称为枚举类)。与传统的Enum Class相比,枚举类提供了更完整的类型安全性。我们使用enum class关键字来定义一个枚举类型,在此基础上,使用关键字enum来定义一个枚举类:

enum class Color : char {
   RED, BLUE, GREEN
};
int main() {
    Color c = Color::RED;
    char red = static_cast<char>(c);
    return 0;
}

在上面的代码中,枚举类类型被指定为char,因此它只能存储char类型的值。c实际上是一个枚举类型的字符类型的实例。我们可以使用static_cast将c的值强制转换为char。如果c的值不是char类型,则编译器会报告一个错误。

七、总结

Enum Class提供了更强的类型安全和更好的作用域管理,同时也解决了原始枚举的一些限制。通过使用Enum Class,我们可以更易于编写和维护类型安全的C++代码。