面试题答案
一键面试C++枚举类型底层存储
在C++中,枚举类型(enum
)的底层存储是整数类型。编译器会为枚举成员分配整数值,默认从0开始,依次递增。如果手动指定了某个枚举成员的值,后续成员的值会在此基础上依次递增。例如:
enum Color {
RED = 1,
GREEN,
BLUE
};
// 这里GREEN的值为2,BLUE的值为3
编译器会选择一个足够表示所有枚举值的整数类型来存储枚举变量。通常情况下,会选择int
,但如果枚举值范围较小,也可能选择char
等更小的整数类型。
枚举类型与整数类型的转换
- 枚举类型转换为整数类型:可以直接进行隐式转换,因为枚举类型本质上就是整数类型的一种受限形式。例如:
enum Weekday {
MONDAY,
TUESDAY,
WEDNESDAY
};
Weekday today = MONDAY;
int num = today; // 隐式转换为整数类型
- 整数类型转换回枚举类型:需要进行显式转换,因为整数类型的值可能不在枚举值的范围内。例如:
int value = 2;
Weekday day = static_cast<Weekday>(value);
转换过程中的风险及避免方法
- 风险:将整数类型转换为枚举类型时,如果整数的值不在枚举定义的范围内,会导致未定义行为。例如:
int wrongValue = 10;
Weekday wrongDay = static_cast<Weekday>(wrongValue); // 未定义行为
- 避免方法:在进行转换之前,可以先检查整数的值是否在枚举值的范围内。例如:
int value = 2;
if (value >= static_cast<int>(MONDAY) && value <= static_cast<int>(WEDNESDAY)) {
Weekday day = static_cast<Weekday>(value);
} else {
// 处理错误情况
}
C++11强类型枚举(enum class)与传统枚举的区别
- 类型安全性:
- 传统枚举:传统枚举的作用域是全局的,不同枚举类型的枚举成员如果名字相同会产生冲突。而且传统枚举可以隐式转换为整数类型,可能导致类型安全问题。
- 强类型枚举(
enum class
):强类型枚举有自己的作用域,不同enum class
的枚举成员名字不会冲突。并且enum class
不会隐式转换为整数类型,需要显式转换,提高了类型安全性。例如:
enum class Fruit {
APPLE,
BANANA
};
enum class Vegetable {
CARROT,
POTATO
};
// 以下代码会报错,因为不同enum class枚举成员不会隐式转换
// Fruit f = Vegetable::CARROT;
// 必须显式转换
Fruit f = static_cast<Fruit>(static_cast<int>(Vegetable::CARROT));
- 底层存储:
- 传统枚举:底层存储类型由编译器决定,通常为
int
,但可能根据枚举值范围选择其他整数类型。 - 强类型枚举(
enum class
):默认底层存储类型也是int
,但可以显式指定底层存储类型。例如:
- 传统枚举:底层存储类型由编译器决定,通常为
enum class SmallEnum : char {
VALUE1,
VALUE2
};
这样SmallEnum
的底层存储类型就是char
,可以节省内存空间。