enum
的主要缺点
1、类型不明确
-
首先,无法指定数据类型,导致我们无法明确枚举类型所占的内存大小。这种麻烦在结构体当中尤为突出,特别是当我们需要内存对齐和填充处理的时候。
#include <iostream> enum Version { Ver1 = 1, Ver2, Ver3 }; struct MyStruct { MyStruct(Version ver) { this->Ver = ver; } Version Ver; //Ohters... }; int main() { MyStruct m(Version::Ver1); std::cin.get(); return 0; }
此时我们的解决办法还是:不使用enum
#include <iostream> enum Version { Ver1 = 1, Ver2, Ver3 }; struct MyStruct { MyStruct(Version ver) { this->Ver = ver; } unsigned char Ver;//将enum Version转为unsigned char类型 //Ohters... }; int main() { MyStruct m(Version::Ver1); std::cin.get(); return 0; }
-
其次,当我们使用
enum
时,我们无法决定编译器底层是如何对待enum
的(比如:signed
和unsigned
)。#include <iostream> enum MyEnum { num1 = 1, num2 = 2, numn = 0xFFFFFF00U }; int main() { std::cout << num1 << std::endl; std::cout << num2 << std::endl; std::cout << numn << std::endl; std::cin.get(); return 0; }
VS2015运行结果:
1 2 -256
CodeBlocks运行结果:
1 2 4294967040
在
numn=0xFFFFFF00U
;中,我们希望0xFFFFFF00
表现为unsigned
。但是不同的编译器其标准也不同。这就给我们的程序带来了许多的不确定性。
2、enum
的作用域
例如:
#include <iostream>
enum color{red,blue};//定义拥有两个成员的enum,red和blue在enum的大括号外部可以直接访问,而不需要使用域运算符。
int main() {
std::cout << blue << std::endl;
std::cin.get();
return 0;
}
// 结果为1
就如上面的代码,我们可以在blue的大括号之外访问它,color的成员被泄露到了该文件的全局作用域中(虽然它尚不具备外部链接性)。可以直接访问,而不需要域运算符的帮助。但是这不是关键,有时我们反而觉得非常方便。下面才是问题所在:
-
问题:无法定义同名的枚举成员
enum color { red, blue }; //enum MyEnum { red, yellow }; ERROR, 重定义;以前的定义是“枚举数”
-
解决:可以使用命名空间,但形式上略显麻烦。
enum class
和enum struct
1、声明:
enum class Name : TypeName {name1, name2......};
2、类型转换保护
与整形之间不会发生隐式类型转换,但可以强制转换
#include <iostream>
enum class color { red, green, yellow};
int main() {
//int res(color::red); //ERROR , “初始化”: 无法从“color”转换为“int”
//color col(2);//ERROR , “初始化”: 无法从“int”转换为“color”
//强转
int res(static_cast<int>(color::red));//OK
color col(static_cast<color>(1));//OK
std::cin.get();
return 0;
}
3、指定底层数据类型
enum class color:unsigned char{red,blue};
enum calss colorb:long long{yellow,black};
4、作用域
#include <iostream>
enum class color { red, green, yellow};
enum class colorX { red, green, yellow };
int main() {
//使用域运算符访问枚举体成员,强转后打印
std::cout << static_cast<int>(color::red) << std::endl;
std::cout << static_cast<int>(colorX::red) << std::endl;
std::cin.get();
return 0;
}