我听到一些人建议在c++中使用枚举类,因为它们的类型安全。
但这到底是什么意思呢?
我听到一些人建议在c++中使用枚举类,因为它们的类型安全。
但这到底是什么意思呢?
当前回答
值得注意的是,在这些答案之上,c++ 20解决了枚举类的一个问题:冗长。想象一个假设的枚举类Color。
void foo(Color c)
switch (c) {
case Color::Red: ...;
case Color::Green: ...;
case Color::Blue: ...;
// etc
}
}
与普通枚举变体相比,这是详细的,其中名称在全局作用域中,因此不需要用Color::作为前缀。
然而,在c++ 20中,我们可以使用using enum将枚举中的所有名称引入到当前作用域,从而解决了这个问题。
void foo(Color c)
using enum Color;
switch (c) {
case Red: ...;
case Green: ...;
case Blue: ...;
// etc
}
}
所以现在,没有理由不使用枚举类。
其他回答
不隐式转换为int 可以选择哪种类型的底层 ENUM命名空间,避免污染发生 与普通类相比,可以向前声明,但没有方法
还有一件事没有明确提到——作用域特性提供了一个选项,可以让枚举和类方法具有相同的名称。例如:
class Test
{
public:
// these call ProcessCommand() internally
void TakeSnapshot();
void RestoreSnapshot();
private:
enum class Command // wouldn't be possible without 'class'
{
TakeSnapshot,
RestoreSnapshot
};
void ProcessCommand(Command cmd); // signal the other thread or whatever
};
c++有两种类型的enum:
枚举类 简单的枚举
下面是几个关于如何声明它们的例子:
enum class Color { red, green, blue }; // enum class
enum Animal { dog, cat, bird, human }; // plain enum
这两者之间有什么区别?
枚举类——枚举器名称是枚举的本地名称,它们的值不会隐式转换为其他类型(比如另一个枚举或int)。 普通枚举——枚举器名称与枚举及其所在的枚举在同一作用域内 值隐式地转换为整数和其他类型
例子:
enum Color { red, green, blue }; // plain enum
enum Card { red_card, green_card, yellow_card }; // another plain enum
enum class Animal { dog, deer, cat, bird, human }; // enum class
enum class Mammal { kangaroo, deer, human }; // another enum class
void fun() {
// examples of bad use of plain enums:
Color color = Color::red;
Card card = Card::green_card;
int num = color; // no problem
if (color == Card::red_card) // no problem (bad)
cout << "bad" << endl;
if (card == Color::green) // no problem (bad)
cout << "bad" << endl;
// examples of good use of enum classes (safe)
Animal a = Animal::deer;
Mammal m = Mammal::deer;
int num2 = a; // error
if (m == a) // error (good)
cout << "bad" << endl;
if (a == Mammal::deer) // error (good)
cout << "bad" << endl;
}
结论:
枚举类应该是首选的,因为它们较少引起可能导致错误的意外。
枚举用于表示一组整数值。
枚举后面的class关键字指定枚举是强类型的,并且枚举数是有作用域的。这样枚举类可以防止意外误用常量。
例如:
enum class Animal{Dog, Cat, Tiger};
enum class Pets{Dog, Parrot};
在这里,我们不能把动物和宠物的价值观混为一谈。
Animal a = Dog; // Error: which DOG?
Animal a = Pets::Dog // Pets::Dog is not an Animal
与普通枚举相比,使用枚举类的基本优点是您可以为两个不同的枚举使用相同的枚举变量,并且仍然可以解析它们(这已经被OP提到为类型安全)。
如:
enum class Color1 { red, green, blue }; //this will compile
enum class Color2 { red, green, blue };
enum Color1 { red, green, blue }; //this will not compile
enum Color2 { red, green, blue };
对于基本枚举,编译器将无法区分红色是指下面语句中的类型Color1还是Color2。
enum Color1 { red, green, blue };
enum Color2 { red, green, blue };
int x = red; //Compile time error(which red are you refering to??)