37.枚举-强类型枚举
37.1 知识点
普通枚举可能存在的问题
1. 命名冲突
多个枚举中存在同名枚举项,会引发命名冲突,并可能和全局变量产生冲突。例如,枚举中有一项叫 Test1
,又有一个全局变量叫 Test1
,打印 Test1
时会报错。
enum E_Test
{
Test1,
Test2,
};
// int Test1 = 1;
又或者另一个枚举中有一项叫 Test1
也会报错:
// enum E_Test2
// {
// Test1,
// Test2,
// };
2. 隐式转换为 int
,不够安全
枚举类型可能会不小心和整数进行混合运算。通常情况下,枚举是不希望参与到计算中的,因为它们是用于处理状态或类型的。
int a = 1 + Test1;
3. 不同枚举类型之间可以进行比较
虽然不同类型的枚举可以进行比较,但逻辑上并不符合常规。例如,E_Test
和 E_Test3
的比较是没有意义的:
enum E_Test3
{
T1,
T2,
};
// if (Test1 == T1)
// {
// }
4. 默认枚举项类型只能是 int
,大材小用
枚举项默认使用 int
类型存储,可能存在空间浪费的情况。
强类型枚举
强类型枚举用于提升枚举的安全性。语法如下:
enum class 枚举名
{
各枚举项...
};
进行枚举变量赋值时,指明枚举类型:
枚举类型 变量 = 枚举类型::枚举项
主要作用:
- 避免命名冲突
若多个枚举中有同名枚举项,强类型枚举能够避免冲突。
enum class E_Test1 : short
{
Test1,
Test2,
};
E_Test1 t = E_Test1::Test1;
enum class E_Test2 : long long
{
Test1,
Test2,
};
E_Test2 t2 = E_Test2::Test1;
- 强类型枚举无法隐式转换为
int
,需要使用static_cast<int>
进行显式转换
这可以避免不小心将枚举和整数混用。
// 强类型枚举无法隐式转换为 int
// int a = 1 + t; // 错误
cout << static_cast<int>(t) << endl; // 0
E_Test2 t2 = E_Test2::Test1;
cout << static_cast<int>(t2) << endl; // 0
- 禁止不同类型的枚举之间进行比较
强类型枚举可以禁止不同类型的枚举进行比较:
// 不同枚举不能直接比较
// if (t == t2)
// {
//
// }
- 可以指定枚举的底层类型
通过在枚举类型后加冒号指定类型。默认情况下,枚举存储项的类型是 int
,但可以指定为其他整型类型。
enum class E_Test33 : short
{
Test1,
Test2,
};
E_Test33 t33 = E_Test33::Test1;
enum class E_Test44 : long long
{
Test1,
Test2,
};
E_Test44 t44 = E_Test44::Test1;
示例:
//不会命名冲突了
E_Test1 t = E_Test1::Test1;
E_Test1 t3 = E_Test1::Test2;
//不能直接计算
//int a = 1 + t;
//强类型枚举不会隐式转换为int了 需要我们自己转换
cout << static_cast<int>(t) << endl;//0
E_Test2 t2 = E_Test2::Test1;
cout << static_cast<int>(t2) << endl;//0
//不同枚举不能直接比较
//if (t == t2)
//{
//}
//同类型枚举可以直接比较
if (t == t3)
{
}
//可以指定枚举的底层类型 在后面加冒号指定类型 查看一个枚举变量大小
cout << sizeof(t33) << endl;//2 short
cout << sizeof(t44) << endl;//8 long long
37.2 知识点代码
Lesson37_枚举_强类型枚举.cpp
#include <iostream>
using namespace std;
#pragma region 知识点一 普通枚举可能存在的问题
//1.命名冲突
// 多个枚举中存在同名枚举项,会引发命名冲突
// 会和全局变量产生冲突
//例如枚举中有一项叫Test1 又有一个全局变量叫Test1 打印Test1时会报错
enum E_Test
{
Test1,
Test2,
};
//int Test1 = 1;
//又或者另一个枚举中有一项叫Test1 也会报错
//enum E_Test2
//{
// Test1,
// Test2,
//};
//2.隐式转换为int,不够安全
// 可能会不小心和整数进行混合运算
//3.不同枚举类型之间可以产生比较
// 不太符合逻辑
//比如E_Test和E_Test3比较
enum E_Test3
{
T1,
T2,
};
//4.默认枚举项类型只能是int,大材小用了
#pragma endregion
#pragma region 知识点二 强类型枚举
//强类型枚举是用来提升枚举的安全性
//语法:
// enum class 枚举名
// {
// 各枚举项...
// };
//进行枚举变量赋值时 指明枚举类型
// 枚举类型 变量 = 枚举类型::枚举项
//主要作用:
//1.避免命名冲突
// 若多个枚举中有同名枚举项,会引发冲突
enum class E_Test1 : short
{
Test1,
Test2,
};
E_Test1 t = E_Test1::Test1;
enum class E_Test2 : long long
{
Test1,
Test2,
};
E_Test2 t2 = E_Test2::Test1;
//2.强类型枚举无法隐式转换为整型,需要使用 static_cast<int>(枚举值) 进行显示转换
// 可以避免不小心将枚举和整数混用
//3.可以禁止不同类型的枚举之间进行比较
//4.可以指定枚举的底层类型 在后面加冒号指定类型
// 不加默认枚举中存储的枚举项是int类型
// 我们可以利用强类型枚举指定其存储类型
// 但是必须是整型类型,不能是其他类型
enum class E_Test33 : short
{
Test1,
Test2,
};
E_Test33 t33 = E_Test33::Test1;
enum class E_Test44 : long long
{
Test1,
Test2,
};
E_Test44 t44 = E_Test44::Test1;
#pragma endregion
int main()
{
std::cout << "强类型枚举\n";
#pragma region 知识点一 普通枚举可能存在的问题
//1.命名冲突
// 多个枚举中存在同名枚举项,会引发命名冲突
// 会和全局变量产生冲突
//cout << Test1 << endl;//如果又重复定义Test1会报错
//2.隐式转换为int,不够安全
//可能会不小心和整数进行混合运算
//枚举一般是不太希望它参与到计算当中
//因为枚举是希望用于处理状态、类型的
//int a = 1 + Test1;
//3.不同枚举类型之间可以产生比较
// 不太符合逻辑
//不同类型的枚举虽然能够比较 但是逻辑上是不太合理的
//因为 不同枚举之间代表的是不同的含义
//比如E_Test和E_Test3比较
/*if (Test1 == T1)
{
}*/
#pragma endregion
#pragma region 知识点二 强类型枚举
//不会命名冲突了
E_Test1 t = E_Test1::Test1;
E_Test1 t3 = E_Test1::Test2;
//不能直接计算
//int a = 1 + t;
//强类型枚举不会隐式转换为int了 需要我们自己转换
cout << static_cast<int>(t) << endl;//0
E_Test2 t2 = E_Test2::Test1;
cout << static_cast<int>(t2) << endl;//0
//不同枚举不能直接比较
//if (t == t2)
//{
//}
//同类型枚举可以直接比较
if (t == t3)
{
}
//可以指定枚举的底层类型 在后面加冒号指定类型 查看一个枚举变量大小
cout << sizeof(t33) << endl;//2 short
cout << sizeof(t44) << endl;//8 long long
#pragma endregion
}
37.3 练习题
枚举和强类型枚举在语法上有什么区别?
普通枚举声明:
enum 枚举名
{
枚举项, ..... , ...... , ....
}
普通枚举变量声明:
枚举类型 变量名 = 枚举项名;
强类型枚举声明:
enum class 枚举名 : 整形类型 (可选)
{
枚举项, ..... , ...... , ....
}
强类型枚举变量声明:
枚举类型 变量名 = 枚举类型::枚举项;
强类型枚举和普通枚举在使用上有什么区别?
声明方式不同
强类型枚举不存在普通枚举的命名冲突问题
强类型枚举不会像普通枚举一样隐式转换为int,需要用
static_cast<int>()
进行转换强类型枚举不能彼此比较,普通枚举可以(但是不建议)
强类型枚举可以指定整形存储的类型,如果不指定会和普通枚举一样用int
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com