【问题标题】:enum vs static consts枚举与静态常量
【发布时间】:2013-11-08 18:01:53
【问题描述】:

我目前正在考虑命名空间枚举或命名空间静态常量组是否更可取的问题。 什么应该是默认选择,为什么?

选项 1:

namespace Direction
{
    enum Direction
    {
        north,
        east,
        south,
        west,
    };
}

选项 2:

namespace Direction
{
    static const unsigned char north = 0;
    static const unsigned char east = 1;
    static const unsigned char south = 2;
    static const unsigned char west = 3;
}

两者各有优缺点。

专业枚举:

  1. 一些类型安全:

    void foo(Direction dir); // the compiler won't allow you to just pass an int or a value of an unrelated enum without explicitly casting it
    

反枚举:

  1. 类型安全相当有限:

    enum A
    {
        Entry1 = 1
    };
    
    enum B
    {
        Entry2 = 10
    };
    
    A a;
    if(a == Entry2)
        ; // ouch!
    
  2. 不支持除 int 以外的任何其他类型 - 在 C++ 11 之前,不能只拥有例如 long long、short 或 char 的枚举

  3. 枚举的命名空间不是最理想的

    1. 如果不将枚举封装到单独的命名空间中,那么它的所有成员都会污染周围的命名空间。

    2. 如果确实将枚举包装到一个单独的命名空间中,那么当使用枚举本身作为一种类型时会得到一些冗余: 然后必须以 Direction::Direction 的方式声明一个方向变量(当不执行“使用 Direction::Direction”时,这将让他们再次污染外部命名空间(最后在代码的那部分,其中使用指令生效)),以便能够以 Direction::north 的方式命名其成员,而不仅仅是北

专业静态常量:

  1. 在 C++ 11 之前的 C++ 中提供更好的类型支持 - 例如,可以将 unsigned char 等类型用于常量
  2. 适当的作用域 - 不污染外部命名空间,无需通过 using 指令明确要求(即使在有限的范围内)

对比静态常量:

  1. 类型安全性甚至比枚举还差 - 再也不能像这样声明函数原型了:

    void foo(Direction dir);
    

    但必须通过以下方式进行:

    void foo(unsigned char dir); // now each variable of type unsigned char or of a type that can implicitly be casted into unsigned char can be passed, even if its totally unrelated to the expected "enumeration" or if the value does not match the value of any of the expected consts
    

编辑: 在这里,我发现了一篇关于枚举类型安全限制的有趣文章: http://www.drdobbs.com/enumerations/184401797

【问题讨论】:

  • 枚举是为此目的,它们不占用内存(如果不使用),并且输入方式更少
  • 在您的第二个示例中,north 分配给了什么?使用enum,您可以使用默认值,或者您可以指定应该使用哪个常量值。仅类型检查是值得的。不要做其他选择。
  • 我不明白问题的重点。如果您要枚举 事物(例如基本方向)并且您应该具有“类型安全性”,那么请使用enums。 static 变量适用于其他一系列问题。
  • @aaronman: afaik 一个静态 const 仅在其地址被引用时才占用内存,否则即使使用它也不占用任何内存。
  • "不支持除 int 以外的任何其他类型 - 在 C++ 11 之前 [...]" 枚举(即使在 C++03 中)是具有未指定的底层类型——这个底层类型不必是int [dcl.enum]/5:“枚举的底层类型是一个可以表示所有枚举值的整数类型在枚举中定义。由实现定义的整数类型用作枚举的基础类型,除非基础类型不得大于int,除非枚举数的值不能适合int或@ 987654335@。”

标签: c++ enums c++03


【解决方案1】:

最大的区别在于打字。枚举具有不同的类型; 静态 const 必须有一个现有的整数类型(尽管 它可以在其他地方使用)。哪个更可取取决于 你想要什么:对于Direction,你可能想要 一个独特的类型,枚举更可取。在其他情况下,什么 你真正想要的是一个整数类型的命名常量,比如说 作为数组的维度。在这些情况下, static const 是 可能更可取。

【讨论】:

    【解决方案2】:

    C++11 solves 通过强类型枚举和改进的范围界定所有对立枚举点。

    对于像您的基本方向示例这样的一组固定值,我会使用枚举。

    【讨论】:

    • 想详细解释一下吗? C++11 枚举是否保证一定的整数大小?枚举类型和枚举常量是否保证为同一类型?如果是这样,那将是枚举的一个急需的重大改进。至少在 C11 中,枚举仍然像以前一样晦涩。
    【解决方案3】:

    使用枚举,您可以将属于一个概念的所有常量联系在一起(使用名为 enum 的唯一 c++ 标识符)。

    Herb Sutter 写过更喜欢新风格的演员表 (static_cast) 而不是 C 演员表。他的一个论点(除其他外)是可以在源代码中使用正则表达式找到它们。

    回到你的问题,这意味着如果你使用enum,你可以通过你的代码库来查找要一起使用的常量的出现。这对于命名空间中的常量是不可能的。

    【讨论】:

      猜你喜欢
      • 2011-01-14
      • 1970-01-01
      • 2014-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-26
      • 2014-06-29
      相关资源
      最近更新 更多