• C++11 强枚举类型


    enum class的优点

    C++11 推出的 强类型枚举(enum class) 的主要优势在于:

    • 提供了更好的类型安全:不能直接看做整型数据,枚举就是枚举,不能做整型相关的运算
    • 以及更严格的作用域控制:带作用域,其类名就是作用域
    • 可以显示指定其底层存储类型,默认为int。(为其他的比如char的话 有什么作用和意义我不太清楚,也没见过)

    示例:

    #include 
    enum class Color : int
    {    
        Red,
        Green,
        Blue
    };
    enum class Car : int
    {
    	Red,
    	Green,
    	Blue
    };
    
    int main() {
    	// 1、不会冲突,枚举值都有各自的作用域
        Color color = Color::Red;
    	Color Car = Car::Red;
        
        // 2、不能隐式转换成int
        // int value = color;
        
        if (color == Color::Red) 
        {
            std::cout << "The color is red." << std::endl;
        }
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    enum 的缺点(传统C风格枚举)

    • 缺乏类型安全性: 可以隐式转换为整数。不同枚举类型的值混淆。比如:

      enum Color {red, green}; 
      enum Car {BMW, Audi};
      
      int main() {
      	Color color = red;
      	Car car = BMW;
      	if (color == car)   // 这个if 是能通过编译的,很离谱	
      	...
      }	
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • 全局作用域: 传统的C风格枚举的成员在全局作用域中定义,这可能导致潜在的命名冲突。

      enum Color {Red, Green, Blue};// 第一个文件
      enum Color {Black, White};// 第二个文件
      
      int main() {
          enum Color color = Red; // 编译器不知道Red是哪个枚举的成员,因为有两个名为Color的枚举
          printf("Color: %d\n", color); // 编译错误
      	...
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

      给每个枚举添加命名空间可以解决,其实也不太麻烦。。

    • 编译器可能会报警告 (但可以全局禁用它的警告)

    • 没有底层类型: 传统的C风格枚举没有明确的底层类型,通常默认为int。这可能导致不同编译器和平台之间的兼容性问题,因为int的大小可能会有所不同


    重要:使用enum 还是enum class

    取决于具体需求!并不是 enum class 就一定好!

    enum 的缺点恰恰就是它的优点

    enum 优点

    • 整型值: enum 可以完全等同于一个整型,因此可以像整数一样进行运算。这使得它非常适合需要进行位运算或其他整数运算的情况。

    • 简洁: enum 的定义相对简单,不需要额外的运算符重载或其他复杂的结构。这使得代码编写和阅读都更为直观。

    比如,你希望你的枚举值支持位运算,如果用enum class,你需要重载你所需要的位运算操作符

    #include 
    
    
    enum class FileAccess 
    {
        READ = 1 << 0,			// 1
        WRITE = 1 << 1,			// 2
        EXECUTE = 1 << 2		// 4  为了方便做位运算,每个枚举值对应一个比特位为1
    };
    
    // 定义按位或运算符的重载
    FileAccess operator|(FileAccess lhs, FileAccess rhs) 
    {
        using T = std::underlying_type_t<FileAccess>;
        return static_cast<FileAccess>(static_cast<T>(lhs) | static_cast<T>(rhs));
    }
    // ...其他运算符重载,如:& ^ ~ |= &= ^= 
    // 属实非常麻烦,如果还有其他类似的enum class 还要每个都写一遍,==噩梦
    
    int main() 
    {
        FileAccess myPermissions = FileAccess::READ | FileAccess::WRITE;
    
    	if (myPermissions & FileAccess::WRITE) 
    	{
    	    // 有写权限
    	}
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    而使用enum,就非常简洁方便。

    #include 
    
    enum FileAccess 
    {
        READ = 1 << 0,			
        WRITE = 1 << 1,		
        EXECUTE = 1 << 2	
    };
    
    int main() 
    {
        FileAccess myPermissions = FileAccess::READ | FileAccess::WRITE;
    
        if (myPermissions & FileAccess::WRITE) {
     		// ....
        }
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 相关阅读:
    程序员创始股东协议
    C#编程题分享(3)
    Grafana监控系统的构建与实践
    计算机网络:应用层 (DNS FTP)
    【QT】Ubuntu 编译安装 QT 5.12.7 源码
    如何利用人才测评系统提升企业招聘效率
    C# 将一种类型的数组转换为另一种类型的数组
    华为云云耀云服务器L实例评测|Docker部署及应用
    5.中间件
    神经网络的可解释性方法
  • 原文地址:https://blog.csdn.net/Motarookie/article/details/133907545