代码之家  ›  专栏  ›  技术社区  ›  sharptooth

是否有理由使用EnUM在C++代码中定义单个常量?

  •  14
  • sharptooth  · 技术社区  · 15 年前

    定义要在函数内部使用的整数常量的典型方法是:

    const int NumbeOfElements = 10;
    

    在类中使用相同:

    class Class {
    ...
        static const int NumberOfElements = 10;
    };
    

    然后它可以用作固定大小的数组绑定,这意味着它在编译时是已知的。

    很久以前,编译器不支持后一种语法,这就是使用枚举的原因:

    enum NumberOfElementsEnum { NumberOfElements = 10; }
    

    现在几乎所有广泛使用的编译器都支持in函数 const int 在课堂上 static const int 语法是否有任何理由为此目的使用枚举?

    9 回复  |  直到 11 年前
        1
  •  25
  •   Chowlett    11 年前

    原因主要是简洁。首先,一个 enum 可以是匿名的:

     class foo {
        enum { bar = 1 };
     };
    

    这有效地介绍了 bar 作为一个积分常数。请注意,上面的短于 static const int .

    而且,没有人可能写 &bar 如果是 枚举 成员。如果您这样做:

     class foo {
        static const int bar = 1;
     }
    

    然后你的客户会这样做:

     printf("%p", &foo::bar);
    

    然后他会得到一个编译时链接器错误 foo::bar 没有定义(因为,作为左值,它没有定义)。在实践中,按照目前的标准,在任何地方 酒吧 当整型常量表达式不是 必修的 (即仅允许的情况下),它要求对 foo::bar. 需要这样一个表达式的地方是: 枚举 初始化器, case 标签,类型中的数组大小(除外 new[] )和整型的模板参数。因此,使用 酒吧 任何其他地方都需要一个定义。见 C++ Core Language Active Issue 712 更多信息-目前还没有提议的解决方案。

    在实践中,现在大多数编译器对此都比较宽容,并且会让您摆脱对 静态常量int 不需要定义的变量。然而,角落案件可能会有所不同,但是,许多人认为只使用匿名更好。 枚举 因为这一切都是清晰的,完全没有歧义。

        2
  •  9
  •   sbi    15 年前

    在类定义中直接定义静态常量是C++的后来添加,许多仍然坚持使用旧的方法。 enum 为此。甚至可能还有一些旧的编译器仍在使用,它们不支持直接在类定义中定义的静态常量。

        3
  •  5
  •   Frerich Raabe    15 年前

    在你的例子中,我也会用到一个常数。但是,在其他情况下 可以 正在添加其他相关常量。这样地:

    const int TextFile = 1; // XXX Maybe add other constants for binary files etc.?
    

    在这种情况下,我会立即使用具有单个值的枚举,如下所示:

    enum FileType {
        TextFile = 1
        // XXX Maybe add other values for binary files etc.?
    }
    

    原因是,当我在switch表达式中使用常量值时,编译器可以发出警告,如:

    FileType type;
    // ...
    switch ( type ) {
        case TextFile:
           // ...
    }
    

    如果我决定添加另一个与现有值相关的常量值(在本例中是另一种文件类型),几乎所有编译器都会发出警告,因为switch语句中不处理新值。

    如果我使用了“int”和常量,编译器就没有机会发出警告。

        4
  •  5
  •   Gorpik    15 年前

    使用“enum hack”的唯一原因是,正如您在问题中所说,旧编译器不支持类常量定义。所以,除非您怀疑您的代码将被移植到一个旧的编译器,否则您应该在const到期的地方使用const。

        5
  •  5
  •   jrbjazz    15 年前

    使用枚举有一个优点。枚举类型是一种类型,因此如果您定义,例如:

    enum EnumType { EnumValue1 = 10, EnumValue2 = 20 ... };
    

    你的功能是:

    void Function1(EnumType Value)
    

    编译器检查是否正在将枚举枚举枚举类型的成员传递给函数,因此只有参数值的有效值才会是EnumValue1和EnumValue2。如果使用常量并将函数更改为

    void Function1(int Value)
    

    编译器检查是否正在向函数传递int(任何int、常量、变量或文本)。

    枚举类型适合对相关常量值进行分组。对于一个常量值,我看不到任何优势。

        6
  •  3
  •   Paolo Tedesco    15 年前

    我认为没有理由使用枚举,而且实际上最好使用 static const int 为此,因为枚举有自己的类型(即使隐式转换为整数)。

        7
  •  2
  •   Tobias Langner    15 年前

    这两者有区别。据我所知,Enums没有地址。不过静态常量可以。因此,如果有人获取const static int的地址,丢弃const,他可以修改该值(尽管编译器可能会忽略更改,因为他认为它是const)。这当然是纯粹的邪恶,你不应该这样做-但编译器不能阻止它。这不可能发生在Enums上。

    当然,如果你(出于某种原因)需要那个警察的地址,你需要静态警察。

    简而言之,枚举是右值,而常量static int是左值。参见 http://www.embedded.com/story/OEG20011129S0065 了解更多详细信息。

        8
  •  1
  •   SadSido    15 年前

    嗯,便携性 使用枚举的一个好理由。这很好,因为您不必担心编译器是否支持“static const int s=10”…

    另外,据我所知,静态变量必须在某个地方定义并声明,并且枚举值必须只声明。

        9
  •  -2
  •   Ami    15 年前

    底线-使用常量。

    更多细节:

    我不是C++专家,但这似乎是一个更一般的设计问题。

    如果不是必须的,并且您认为枚举增长到一个以上的值的概率非常低/不存在,那么使用正则常量。 即使您是错误的,并且在将来的某个时候会有更多的值,使枚举成为正确的选择——一个简单的重构,然后您将常量更改为枚举。