Enum

枚举

  • 一种取值受限的特殊类型
    • 无作用域枚举
      enum Color {  
        Red,  // Red的作用域不在Color内,而是整个文件,因此main函数中可以直接使用“Red”
        Yellow
      };
      
      enum Color2 {  
        Red,  // Red的作用域不在Color内,而是整个文件,因此main函数中可以直接使用“Red”
        Yellow
      };
      
      namespace ABC {
        enum Color {
          Red,  // Red的作用域不在Color内,而是ABC域内
          Yellow
        };
      }
      
      class DEF {
      public:
        enum Color {
          Red,  // Red的作用域不在Color内,而是DEF类内
          Yellow
        };
      };
      int main() {
        Color x = Red;
        Color2 x2 = Red;  // 这里的Red和上面的Red产生冲突了,这就是无作用域的坏处
        ABC::Color y = ABC::Red;
        DEF::Color z = DEF::Red;
      }
      
    • 有作用域枚举(C++11起)
      enum class Color {  
        Red,  // Red的作用域在Color内
        Yellow
      };
      
      enum class Color2 {  
        Red,  // Red的作用域在Color2内
        Yellow
      };
      
      int main() {
        Color x = Color::Red;
        Color x2 = Color2::Red;  // 无冲突了
      }
      
    • 枚举项缺省使用0初始化,依次递增,可以使用常量表达式来修改缺省值
      enum class Color {  
        Red,
        Yellow = 100,
        Green
      };
      
      class A {
      public:
        enum {x = 3};  // 早期的C++代码通过这种方式在类的内部定义一个编译期常量
        // constexpr static int x = 3;  // 这种方式更好,但早期C++不包含constexpr,所以用上面的方法代替
      };
      
      int main() {
        std::cout << Color::Green << std::endl;  // 101
      }
      
    • 可以为枚举指定底层类型,表明了枚举项的尺寸
      enum Color {  
        Red,
        Yellow = 100,
        Green
      };
      
      enum Color2 : char {  
        Red,
        Yellow = 100,
        Green
      };
      
      int main() {
        std::cout << sizeof(Color) << std::endl;  // 4(int)
        std::cout << sizeof(Color2) << std::endl;  // 1
      }
      
    • 无作用域的枚举项可以隐式转换为整数,也可以用static_cast互相转换;有作用域的枚举项不可以
      enum Color {  
        Red,
        Yellow = 100,
        Green
      };
      
      void fun(Color x) {
      
      }
      
      enum class Color2 {  
        Red,
        Yellow = 100,
        Green
      };
      
      int main() {
        fun(100);  // 编译失败
        fun(static_cast<Color>(100));  // 编译成功
      
        std::cout << Red << std::endl;  // 0
        std::cout << Color2::Red << std::endl;  // 编译失败
        std::cout << static_cast<int>(Color2::Red) << std::endl;  // 编译成功
      }
      
    • 注意区分枚举的声明和定义
      enum Color;
      enum Color2 : int;
      enum class Color3;
      
      int main() {
        Color x;  // 即使在别的文件中有定义,还是失败;因为在这个翻译单元中,编译器不知道Color的具体大小是int还是char还是其他大小,无法分配内存
        Color2 x;  // 可以编译,Color2的大小确定
        Color3 x;  // 可以编译,有作用域的枚举类型默认是int型
      }
      

Search

    欢迎添加我的微信

    闷骚的程序员

    Table of Contents