文章中的文字可能存在语法错误以及标点错误,请谅解;
如果在文章中发现代码错误或其它问题请告知,感谢!
若一个变量只有有限的几种可能,我们可以定义枚举(enumeration)类型,比如一个星期中取值范围只能是星期一至星期日,性别的分类只能有男或女。
默认情况下,枚举成员值从0开始,其后的枚举成员值以依次1。我们也可以显示指定枚举成员值,则其后的枚举成员值在指定的成员值依次加1。枚举成员值必须是常量表达式。
在C++11新标准中引入了限定作用域的枚举类型(enum class),所以在C++11中枚举类型可分为不限定作用域(enum)以及限定作用域(enum class)两种。在限定作用域的enum class中,枚举成员的作用域限定在枚举类型所声明的作用域中,所以当某个更大的作用域中包含enum class则该enum class中的枚举成员的作用域也只限定在该enum class中。
本文章只简单介绍限定作用域的枚举类型(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 枚举名
{
枚举元素表列
};
#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
在限定作用域的枚举类型中,枚举成员的名字遵循常规的作用域准则,并且在枚举类型的作用域外是不可访问的。与之相反,在不限定作用域的枚举类型中,枚举成员的作用域与枚举类型本身的作用域相同。
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;
}
不限范围的枚举类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;
}
在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; //正确,提前指定枚举成员默认类型,可以声明前置
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