如何在C++中使用枚举
How to use enums in C++
>假设我们有一个如下所示的enum
:
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
我想创建此enum
的实例并使用适当的值对其进行初始化,所以我这样做:
Days day = Days.Saturday;
现在我想用现有的enum
值检查我的变量或实例,所以我这样做:
if (day == Days.Saturday)
{
std::cout << "Ok its Saturday";
}
这给了我一个编译错误:
错误:"." 标记之前的预期主表达式
所以要清楚,说:
if (day == Days.Saturday) // Causes compilation error
和
if (day == Saturday)
?
这两个实际上指的是什么,一个是可以的,一个会导致编译错误?
这段代码是错误的:
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Days.Saturday;
if (day == Days.Saturday)
因为Days
不是范围,也不是对象。它是一种类型。类型和类型本身没有成员。你写的相当于std::string.clear
. std::string
是一种类型,因此不能在其上使用.
。 在类的实例上使用.
。
不幸的是,枚举是神奇的,所以类比到此为止。 因为对于类,您可以执行std::string::clear
来获取指向成员函数的指针,但在 C++03 中,Days::Sunday
无效。 (这很可悲(。 这是因为C++(在某种程度上(与 C 向后兼容,而 C 没有命名空间,因此枚举必须在全局命名空间中。 所以语法很简单:
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Saturday;
if (day == Saturday)
幸运的是,迈克·西摩(Mike Seymour(观察到,这已经在C++11中得到解决。将enum
更改为enum class
,它就会获得自己的范围;因此,Days::Sunday
不仅有效,而且是访问Sunday
的唯一方法。快乐的日子!
其中大部分应该会给你编译错误。
// note the lower case enum keyword
enum Days { Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday };
现在,Saturday
、Sunday
等可以用作顶级裸常量,Days
可以用作类型:
Days day = Saturday; // Days.Saturday is an error
同样,稍后要测试:
if (day == Saturday)
// ...
这些enum
值就像裸常量 - 它们是无作用域的 - 编译器提供了一些额外的帮助:(除非您使用 C++11 枚举类(它们不像对象或结构成员那样封装,例如,您不能将它们称为 Days
的成员。
您将在 C++11 中获得所需的内容,它引入了一个enum class
:
enum class Days
{
SUNDAY,
MONDAY,
// ... etc.
}
// ...
if (day == Days::SUNDAY)
// ...
请注意,这个C++在几个方面与 C 略有不同,一个是 C 在声明变量时需要使用 enum
关键字:
// day declaration in C:
enum Days day = Saturday;
这足以声明您的枚举变量并进行比较:
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Saturday;
if (day == Saturday) {
std::cout << "Ok its Saturday";
}
你可以使用一个技巧来使用你所需要的作用域,只需以这样的方式声明枚举:
struct Days
{
enum type
{
Saturday,Sunday,Tuesday,Wednesday,Thursday,Friday
};
};
Days::type day = Days::Saturday;
if (day == Days::Saturday)
您正在寻找强类型枚举,这是 C++11 标准中提供的一项功能。它将枚举转换为具有作用域值的类。
使用您自己的代码示例,它是:
enum class Days {Saturday, Sunday, Tuesday,Wednesday, Thursday, Friday};
Days day = Days::Saturday;
if (day == Days::Saturday) {
cout << " Today is Saturday !" << endl;
}
//int day2 = Days::Sunday; // Error! invalid
如果以 C++11 之前的C++标准为目标,则使用 ::
作为枚举的访问器将失败。但是一些旧的编译器不支持它,一些 IDE 只是覆盖此选项,并设置旧的 C++ std。
如果您使用的是 GCC,请使用 -std=c++11 或 -std=gnu11 启用 C+11。
枚举不是使用一堆 if 语句,而是非常适合切换语句
我在为游戏构建的关卡构建器中使用了一些枚举/开关组合。
编辑:另一件事,我看到你想要类似的语法;
if(day == Days.Saturday)
etc
您可以在C++中执行此操作:
if(day == Days::Saturday)
etc
这是一个非常简单的例子:
EnumAppState.h
#ifndef ENUMAPPSTATE_H
#define ENUMAPPSTATE_H
enum eAppState
{
STARTUP,
EDIT,
ZONECREATION,
SHUTDOWN,
NOCHANGE
};
#endif
某个文件.cpp
#include "EnumAppState.h"
eAppState state = eAppState::STARTUP;
switch(state)
{
case STARTUP:
//Do stuff
break;
case EDIT:
//Do stuff
break;
case ZONECREATION:
//Do stuff
break;
case SHUTDOWN:
//Do stuff
break;
case NOCHANGE:
//Do stuff
break;
}
如果您仍在使用 C++03 并且想要使用枚举,则应在命名空间中使用枚举。例如:
namespace Daysofweek{
enum Days {Saturday, Sunday, Tuesday,Wednesday, Thursday, Friday};
}
您可以在命名空间之外使用枚举,例如,
Daysofweek::Days day = Daysofweek::Saturday;
if (day == Daysofweek::Saturday)
{
std::cout<<"Ok its Saturday";
}
应该不适用于C++:
Days.Saturday
Days 不是包含可以使用点运算符访问的成员的范围或对象。此语法只是 C# 主义,在C++中是不合法的。
Microsoft长期以来一直维护一个C++扩展,允许您使用 scope 运算符访问标识符:
enum E { A, B, C };
A;
E::B; // works with Microsoft's extension
但这在 C++11 之前是非标准的。在 C++03 中,枚举中声明的标识符仅存在于与枚举类型本身相同的范围内。
A;
E::B; // error in C++03
C++11 使得使用枚举名称限定枚举标识符变得合法,并且还引入了枚举类,这些类为标识符创建一个新作用域,而不是将它们放在周围的作用域中。
A;
E::B; // legal in C++11
enum class F { A, B, C };
A; // error
F::B;
可悲的是,枚举的元素是"全局的"。您可以通过执行day = Saturday
来访问它们。这意味着你不能拥有enum A { a, b } ;
和enum B { b, a } ;
,因为它们处于冲突之中。
虽然C++(不包括 C++11(有枚举,但它们中的值被"泄漏"到全局命名空间中。
如果您不想泄露它们(并且不需要使用枚举类型(,请考虑以下事项:
class EnumName {
public:
static int EnumVal1;
(more definitions)
};
EnumName::EnumVal1 = {value};
if ([your value] == EnumName::EnumVal1) ...
声明枚举值时,C++中的枚举就像被你给它们的名字掩盖的整数(这不是一个定义,只是一个提示它是如何工作的(。
但是代码中有两个错误:
- 拼写
enum
全部小写 - 在周六之前,您不需要
Days.
。 - 如果此枚举是在类中声明的,则使用
if (day == YourClass::Saturday){}
我认为您的根本问题是使用.
而不是::
,这将使用命名空间。
尝试:
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Days day = Days::Saturday;
if(Days::Saturday == day) // I like literals before variables :)
{
std::cout<<"Ok its Saturday";
}
如果我们想要严格的类型安全和作用域枚举,在 C++11 中使用 enum class
是好的。
如果我们必须在 C++98 中工作,我们可以使用 InitializeSahib
给出的建议,San
启用作用域枚举。
如果我们还想要严格的类型安全,下面的代码可以实现类似 enum
.
#include <iostream>
class Color
{
public:
static Color RED()
{
return Color(0);
}
static Color BLUE()
{
return Color(1);
}
bool operator==(const Color &rhs) const
{
return this->value == rhs.value;
}
bool operator!=(const Color &rhs) const
{
return !(*this == rhs);
}
private:
explicit Color(int value_) : value(value_) {}
int value;
};
int main()
{
Color color = Color::RED();
if (color == Color::RED())
{
std::cout << "red" << std::endl;
}
return 0;
}
代码修改自书中的类 Month 示例 有效C++ 3rd:第 18 项
枚举视为一组对象,而应将其视为一个整数,其中每个数值都有一个名称enum Days
以便最好将其声明为 enum Day
。如果要将其包含在命名结构中,请将enum Day
放在如下所示的struct Days
中:
struct Days{
enum Day{
Saturday,
Sunday,
Tuesday,
Wednesday,
Thursday,
Friday
};
};
然后,您将像这样Days::Saturday
地处理它们,并且类型将Days::Day
首先,在枚举中将"E",将"e"设置为小写。
其次,在"Days.Saturday"中删除类型名称"Days"。
第三。。。给自己买一本好C++书。
- 不带大括号的枚举形式
- 枚举环境变量的惯用C++14/C++17方法
- 类似枚举的计算常量
- 如何正确实现和访问运算符的各种自定义枚举器
- 错误:从"int"到枚举c++的转换无效
- C++中构造函数中的枚举
- 访问在 C++ 结构中声明的枚举变量
- 枚举类'classname'的多重定义
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- typedef 枚举和枚举类有什么区别?
- 为什么我的开关/机箱在使用枚举时默认?
- 标准::可选枚举的比较运算符
- C++两个源文件之间共享的枚举的静态实例
- 打印没有铸件的枚举可以在C++中吗?
- 枚举成员与静态 int 成员?
- C++:枚举:错误:应使用标识符而不是"}"
- 带有 c++ 的枚举(输入检查)
- 在 qml 中使用 Q_ENUM 和 Q_PROPERTY 作为枚举类
- 为什么 int 类型的枚举类值不能用作 int
- 在 C++ 中输出枚举类类型的向量元素