[C++11新特性] enum 与 enum class 的区别
enum class 是C++11之后出来的新特性,然而使用的人不多。enum 在这之后称为不限定范围的枚举,enum class称之为限定范围的枚举。就这范围的事情使用方式就大相径庭。
文件目录
- 防止污染空间
- 可以前置声明
- 需要强制转换
一、防止污染空间
enum MyEnum
{
ME_FIRST,
ME_SECOND
}
enum MyEnum2
{
ME_FIRST, ///错误 , 不限定范围的enum不允许这么做
}
通常原先的enum的枚举 在同一作用下,重复声明是不允许这样做,但是enum class却可以这样做,因为作用域不一样了。
enum class MyEnum
{
ME_FIRST,
ME_SECOND
}
enum class MyEnum2
{
ME_FIRST,
ME_SECOND /// 编译通过
}
二、可以前置声明
这是enum class最大的优势。前置声明不知道各位熟不熟悉。前置声明最明显的优势是在多个头文件编译时,某个头文件发生变化,不需要重新编译。这个与 effective C++ 的第31条款的降低文件编译依赖性 有异曲同工之妙。
///前置声明
enum class MyEnum;
但是, 普通的enum 就不能前置声明吗,我可没说。其实只要指定了他的底层型别就也可以前置声明了。
enum MyEnum : std::uint8_t;
当然,enum class 也可以指定底层型别
enum class MyEnum : uint32_t
{
ME_FIRST = 0,
ME_SECOND = 0XFFFFFFFF,
}
三、需要强制转换
我认为enum class的缺点。原始的enum具有自动隐式转换的int,虽然这个在许多人眼里觉得这样做可以防止污染空间。但是在使用的时候感觉到非常的繁琐。例如,在作为参数的时候,尤其回调的时候,有时候为了方便,不想在另一个类里面包含有枚举的类,通常是以int做参数。但是这样就会有强转的情况。或者Qt 做界面的时候,数值通常会以int之类的传递,想要enum class 包含常用的数值。
那这个时候就又要强转。effective C++ 第三十一条款 尽量少使用强制类型转换。不光是因为可能会破坏数据结构,而是效率低下,尤其 dynamic_cast 效率低下。但是有些状况下,必须强转。这时候推荐 C++ 新型的强制类型转换。在More effective C++ 提到的不仅标识度高,而且更加的安全。
- 标准C++类型转换有四种:static_cast, dynamic_cast, reinterpret_cast , const_cast。
- static_cast:用法:static_cast (expression)
- 该运算符将expression转换成type-id类型,但是该运算符没有进行运行时类型检查来保证转换的安全性。
- dynamic_cast:用法:dynamic_cast (expression)
- 该运算符将expression转换成type-id类型,其中type-id必须是类的指针、引用或者void *。type-id和expression需要是同一种表示方式(引用对引用,指针对指针)。该运算符主要用于类层次之间的上行和下行转换,或者类之间的交叉转换。类层次间的上下行转换效果和static_cast一样,但是下行转换时,dynamic_cast具有类型检查功能,比static_cast更安全。
- reinterpret_cast:用法:reinterpret_cast (expression)
- type-id必须是一个指针、引用、算术类型、函数指针或成员指针,可以进行指针和整数之间的相互转换,缺点:平台移植性比较差。
- const**_cast**:用法:const_cast (expression)
- 该运算符用来修改类型的const或volatile属性,除了const或volatile修饰外,type-id和expression类型是一样的。如常量指针变成非常量指针,且仍指向原来对象。
- static_cast:用法:static_cast (expression)