枚举值的行为类似于全局变量吗?

时间:2010-11-24 16:54:19

标签: c++ enums

我有两个枚举,如果一个枚举中有一个值与另一个枚举中的值相同:

enum A {joe, bob, doc};
enum B {sunday, monday, doc};

编译器(Visual Studio)抱怨重新定义doc,这意味着它将其视为全局变量。是这样吗?这不是我期望的行为,它迫使我管理项目中所有枚举元素的名称。

任何见解都会有所帮助。

7 个答案:

答案 0 :(得分:9)

Wyatt Anderson已经建议

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

好的,命名约定也可以与基于命名空间的解决方案一起使用......

干杯&第h。,

答案 1 :(得分:8)

它不被视为全局变量。它被视为全局标识符

更确切地说,它被视为enum声明的任何名称空间中的标识符。在您的情况下,这是全局名称空间。

要了解全局标识符和全局变量之间的区别,请尝试获取枚举的地址。 ;)

通常在我定义枚举时,我会添加标识符名称的缩写版本。像这样:

enum InstrumentType { itStock, itEquityOption, itFutureOption };

这有助于避免碰撞。

答案 2 :(得分:5)

C ++ 03中的枚举器与枚举的范围相同。

enum     xxx    {    yyy,       zzz       };
          ^           ^          ^ 
    enumeration    enumerator enumerator

这有时很方便,有时候并不是真的。

在C ++ 0x中,我们将enum class es,更像是C#的enums。在此期间,假设(因为这是语言规则),yyyzzz的范围与xxx完全相同

答案 3 :(得分:4)

如果您希望它们是全局的,请通过将enum放在命名空间中来解决问题并避免命名空间污染:

namespace A
{
    enum A {joe, bob, doc};
}
namespace B
{
    enum B {sunday, monday, doc};
}

A::doc;
B::doc;

答案 4 :(得分:2)

枚举的值存在于声明enum的任何范围内。

以下作品,例如:

enum A {joe, bob, doc};
namespace C { enum B {sunday, monday, doc}; }

class A_class { enum A {joe, bob, doc}; };
class B_class { enum B {sunday, monday, doc}; };

答案 5 :(得分:1)

枚举的值具有枚举本身的范围,即它的声明范围。例如:

enum A {value = 30};

int main()
{
   enum B {value = 32};
   int x = value;
}

x将是32。

答案 6 :(得分:0)

假设我们要声明图形窗口的宽高比。然后按照建议的方式定义枚举值:

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_RATIO_16_9用作例如功能签名:

void SetAspectRatio(AspectRatio aspect)
{
    switch(aspect)
    {
    case AspectRatio::ASPECT_RATIO_16_9:
    // ...
    default:
            std::cerr << "Undefined aspect ratio enum value!" << std::endl;
        }
    }
}

这完全符合我在C#中的预期。