【C++】C++11枚举类型enum class

文章目录

  • 0x00 前言
  • 0x01 枚举类型定义
  • 0x02 限定作用域enum class使用
    • 1.限定作用域enum class定义
    • 2.举例
  • 0x03 enum class与enum区别
    • 1.避免枚举成员重定义
    • 2.避免隐式转换
    • 3.声明前置
  • 0x04 总结

0x00 前言

文章中的文字可能存在语法错误以及标点错误,请谅解;

如果在文章中发现代码错误或其它问题请告知,感谢!

0x01 枚举类型定义

若一个变量只有有限的几种可能,我们可以定义枚举(enumeration)类型,比如一个星期中取值范围只能是星期一至星期日,性别的分类只能有男或女。

默认情况下,枚举成员值从0开始,其后的枚举成员值以依次1。我们也可以显示指定枚举成员值,则其后的枚举成员值在指定的成员值依次加1。枚举成员值必须是常量表达式。

在C++11新标准中引入了限定作用域的枚举类型(enum class),所以在C++11中枚举类型可分为不限定作用域(enum)以及限定作用域(enum class)两种。在限定作用域的enum class中,枚举成员的作用域限定在枚举类型所声明的作用域中,所以当某个更大的作用域中包含enum class则该enum class中的枚举成员的作用域也只限定在该enum class中。

本文章只简单介绍限定作用域的枚举类型(enum class)。

0x02 限定作用域enum class使用

1.限定作用域enum class定义

限定作用域枚举的一般形式如下:

形式1,声明枚举成员类型为int的有作用域枚举类型:

enum class 枚举名 
{   
    枚举元素表列
};

形式2,声明枚举成员类型为类型的有作用域枚举类型:

enum class 枚举名:类型
{   
   枚举元素表列
};

形式3,声明枚举成员类型为int的有作用域枚举类型的不可见枚举声明:

enum class 枚举名 ;

形式4,声明枚举成员类型为类型的有作用域枚举类型的不可见枚举声明:

enum class 枚举名:类型;

注意关键字 enum class 与 enum struct完全等价,所以上述所有形式中的enum class 可由 enum struct替代,例如下列形式等价于形式1:

enum struct 枚举名 
{   
    枚举元素表列
};

2.举例

#include 
using namespace std;

int main() {
	enum class Color { red, green, blue };

	Color r = Color::blue;
	switch(r)
	{
	    case Color::red:
	        std::cout << "red\n";   
	        break;
	    case Color::green:
	        std::cout << "green\n";
	        break;
	    case Color::blue:
	        std::cout << "blue\n";  
	        break;
	}
    return 0;
}

运行结果:

blue

0x03 enum class与enum区别

在限定作用域的枚举类型中,枚举成员的名字遵循常规的作用域准则,并且在枚举类型的作用域外是不可访问的。与之相反,在不限定作用域的枚举类型中,枚举成员的作用域与枚举类型本身的作用域相同。

1.避免枚举成员重定义

enum class的中的枚举成员作用域的范围只限定在enum class声明的作用域中,所以在包含enum class的更大的作用域就可以定义一个与枚举成员变量名相同的变量,降低了对命名空间名的污染:

例1:

#include 
using namespace std;
 enum class Color {red, green, blue};    //red,green,blue只在该括号内有效

int main() {
    auto blue = false;        	//正确,这个blue并不是Color中的blue

	Color a = blue;           	//错误,在作用域范围内没有blue这个枚举量

	Color b = Color::blue;    	//正确

	auto c = Color::blue;    	//正确

	return 0;
}

例2:

#include 
using namespace std;

enum Sex
{
    Girl,  
    Boy
};

int main()
{
    Sex a = Girl;    //正确
    return 0;
}

例3:

#include 
using namespace std;

enum Sex
{
    Girl,  
    Boy
};
enum Student
{
    Girl,  
    Boy
};
int main()
{
	Sex a = Girl;    	//错误:“Girl”与以前的声明冲突
	Student b = Girl;   //错误:“Girl”与以前的声明冲突
	return 0;
}

例4:

#include 
using namespace std;

enum class Sex
{
    Girl,  
    Boy
};
enum class Student
{
    Girl,  
    Boy
};
int main()
{
	Sex a = Sex::Girl;    		//正确
	Student b = Student::Girl;	//正确
	return 0;
}

2.避免隐式转换

不限范围的枚举类enum是可以发生隐式转换的,限定作用域的枚举类型enum class不允许任何隐式转化,可以显示或使用static_cast进行强制转换:

enum class Sex
{
     Girl,  
     Boy
};

int main()
{
    Sex a=Sex::Girl;
    int b =a; 					// 错误,无法从“Girl”隐式转换为“int”。
    int c = int(a); 			// 正确,显示将enum class转换为整数
    int d = static_cast<int>(a);//正确,进行强制转换
    return 0;
}

3.声明前置

在C++11标准中,enum class的枚举类型可以提前声明,因为枚举成员可以使用默认成员类型int,也可以按编程需要修改默认成员类型。而enum未指定枚举成员默认大小,所以必须指定成员类型:

enum class Color;//正确,声明前置,枚举成员默认类型int

enum class Corlor:std:uint32_t;//正确,声明前置,枚举成员默认类型为uint32_t

enum Color; //错误

enum Color:std:uint8_t; //正确,提前指定枚举成员默认类型,可以声明前置

0x04 总结

enum class是限定作用域枚举类型,枚举成员的作用域限定在枚举类型所声明的作用域中。

enum class不允许任何隐式转化,但可以显示或使用static_cast进行强制转换。

enum class可以前置声明默认枚举成员是int,enum本身没有默认枚举成员默认类型,但可以指定枚举成员默认类型从而可以前置声明。

以上。

参考文档:
1.https://www.apiref.com/cpp-zh/cpp/language/enum.html
2.https://blog.csdn.net/fengbingchun/article/details/78535754
3.https://blog.csdn.net/weixin_42817477/article/details/109029172
4.https://www.jb51.net/article/193758.htm

你可能感兴趣的:(#,C/C++)