C++ 枚举值的行为是否类似于全局变量?
我有两个枚举,如果一个枚举中有一个值与另一个枚举中的值同名:C++ 枚举值的行为是否类似于全局变量?,c++,enums,C++,Enums,我有两个枚举,如果一个枚举中有一个值与另一个枚举中的值同名: enum A {joe, bob, doc}; enum B {sunday, monday, doc}; 编译器(VisualStudio)抱怨重新定义了doc,这意味着它将其视为一个全局变量。是这样吗?这不是我期望的行为,它迫使我管理项目中所有枚举元素的名称 任何见解都会有所帮助 C++03中的枚举数与枚举数的作用域相同 enum xxx { yyy, zzz };
enum A {joe, bob, doc};
enum B {sunday, monday, doc};
编译器(VisualStudio)抱怨重新定义了doc
,这意味着它将其视为一个全局变量。是这样吗?这不是我期望的行为,它迫使我管理项目中所有枚举元素的名称
任何见解都会有所帮助 C++03中的枚举数与枚举数的作用域相同
enum xxx { yyy, zzz };
^ ^ ^
enumeration enumerator enumerator
这有时是方便的,有时不是真的
在C++0x中,我们将有
enum类
es,它们更像C#的enum
。同时,只需假设(因为这是语言规则)yyy
和zzz
的作用域与xxx
的作用域完全相同,即枚举的值具有枚举本身的作用域,即它的声明作用域。例如:
enum A {value = 30};
int main()
{
enum B {value = 32};
int x = value;
}
enum A {joe, bob, doc};
namespace C { enum B {sunday, monday, doc}; }
x将是32。枚举的值存在于
枚举
声明的任何范围内
例如,以下工作:
enum A {value = 30};
int main()
{
enum B {value = 32};
int x = value;
}
enum A {joe, bob, doc};
namespace C { enum B {sunday, monday, doc}; }
或
如果希望它们是全局的,请将
enum
s放入命名空间中,以解决问题并避免命名空间污染:
namespace A
{
enum A {joe, bob, doc};
}
namespace B
{
enum B {sunday, monday, doc};
}
A::doc;
B::doc;
它不是一个全局变量。它被视为全局标识符 更准确地说,它被视为
enum
在任何名称空间中声明的标识符。在您的例子中,这是全局名称空间
要了解全局标识符和全局变量之间的区别,请尝试获取枚举的地址。;)
通常,在定义枚举时,我会在前面加上标识符名称的缩写版本。像这样:
enum InstrumentType { itStock, itEquityOption, itFutureOption };
这有助于避免碰撞。怀亚特·安德森已经建议
namespace A
{
enum A {joe, bob, doc};
}
namespace B
{
enum B {sunday, monday, doc};
}
作为“枚举值与枚举本身在同一范围内”问题的修复,允许您编写
A::doc;
B::doc;
但是,当您想要类的enum
本地时,此解决方案不可用,至少在类之外引入人工名称空间时是不可用的
一个简单的解决方案是将每个enum
包装在一个结构中,如下所示:
struct A
{
enum Enum {joe, bob, doc};
};
struct B
{
enum Enum {sunday, monday, doc};
};
这允许使用与命名空间解决方案相同的使用表示法
A::doc;
B::doc;
但它还允许
- 类中的定义
- 通过继承将枚举名称直接引入类,以及
- 通过
对限定符进行本地类内重命名typedef
- 在我看来,在引用枚举类型时需要更加清晰,例如编写
a::enum
干杯&hth.,假设我们要声明图形窗口的纵横比。然后按照建议定义枚举值:
struct __aspect_ratio__
{
enum values
{
ASPECT_RATIO_16_9, // HD video
ASPECT_RATIO_16_2, // *for testing purposes*
ASPECT_RATIO_4_3, // standard monitor
ASPECT_RATIO_3_2, // classic film
ASPECT_RATIO_21_9, // cinemascope
ASPECT_RATIO_1_1 // quadratic window
};
};
typedef __aspect_ratio__::values AspectRatio;
最后的typedef
允许我们使用AspectRatio::ASPECT\u RATIO\u 16\u 9
作为缩写,例如函数签名:
void SetAspectRatio(AspectRatio aspect)
{
switch(aspect)
{
case AspectRatio::ASPECT_RATIO_16_9:
// ...
default:
std::cerr << "Undefined aspect ratio enum value!" << std::endl;
}
}
}
这是一个类型安全的替代方案,不会污染封闭范围。我们能看到更多代码吗?也许问题就在附近。这不是编译器的正常行为,抱歉,我不知道!对于C?@ykatchou也是一样的:如果上面的两行是正在编译的cpp文件中的唯一行,则会发生这种情况。不,但是代码中会有11个错误。尝试编译它,但如果将
enum 1
更改为enum A
并将enum 2
更改为enum B
,则代码将编译,您仍将显示范围。双赢?如果在这个问题的所有答案中没有一个解决了这个可变的问题,我会大笑不止+1我觉得“变量”不是正确的术语,但我没有更好的术语(现在我有了…)