C++中的枚举如何使用

寻技术 C/C++编程 2023年07月12日 98

这篇文章主要介绍了C++中的枚举如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++中的枚举如何使用文章都会有所收获,下面我们一起来看看吧。

    一、枚举是什么

    枚举(enumeration)类型用于存放用户指定的一组整数值(§iso.7.2)。枚举类型的每种取值各自对应一个名字,我们把这些值叫做枚举值(enumerator)。

    二、使用步骤

    枚举类型分为两种:

    1.enum class,它的枚举值名字位于enum的局部作用域内,枚举值不会隐式地转换成其他类型。

    2.普通的enum,它的枚举值名字与枚举类型本身位于同一个作用域中,枚举值隐式地转换成整数。

    普通枚举和类枚举最显著地差异是“作用域”不同和“隐式类型转换”,接下来我们分开讲。

    1.作用域

    枚举类

    枚举名字前面带class修饰符地枚举就是枚举类,它地成员作用域在enum内部,外部是不能直接访问的,需要通过类名::访问。举一个例子:

    enum class Lights{
        red,green,yellow
    };

    你在类外面直接访问red或其它任何元素都是不行的,正确的访问方式是:

    Lights::red

    和类访问公有成员是一样的。

    普通枚举

    普通枚举就是不带class修饰符的枚举,它的枚举值名字与枚举类型本身位于同一个作用域中。不需要通过名字访问,举个例子:

        enum Lights{
            red, green,yellow
        };

    访问方式和类枚举也有显著差别,直接使用枚举值名字就行了。

    red
    //或
    Lights::red;

    和在函数里访问一个局部变量是一样的,不需要显式指定枚举名字,也可以显式指定枚举名字,效果一样的。

    未命名枚举

    还有一种枚举就是既不加class修饰,也不写枚举名字,而是只有枚举值,例如:

    enum{red,green,yellow};

    这种枚举访问方式和普通枚举一样,就是少了一个枚举名访问方式(因为没有名字,所以没法用名字访问)。

    red

    2.隐式类型转换

    枚举常用一些整数类型表示,每个枚举值是一个整数。如果不显式指定枚举值,那么枚举值是默认从0开始的正整数。这一点对于所有的枚举类型都是一样的。

    //枚举类
    enum class Lights{
    red,// 0
    green,// 1
    yellow// 2
    };
    //普通枚举
    enum Lights{
    red,// 0
    green,// 1
    yellow// 2
    };
    //未命名枚举
    enum {
    red,// 0
    green,// 1
    yellow// 2
    };

    不同的是使用class修饰的枚举类型,它的枚举值是不能隐式转换成其他类型的(这里是int)。比如:

    //枚举类
    int ecl = Lights::red;//这是错误的
    //普通枚举
    int el =  Lights::red;//这是正确的
    //未命名枚举
    int l = red;//这是正确的

    3.显式指定枚举值类型

    如果我们不显式指定枚举值类型,那么枚举值默认是带符号或无符号的整型。我们也可以显式指定枚举值类型为char或其他类型,例如:

    enum class Lights:int{red,green,yellow};//sizeof(Lights) == 4
    enum class Lights:char{red,green,yellow};//sizeof(Lights) == 1

    4.指定枚举值的值

    前面我们知道如果不显式指定枚举值的话,默认是int,而且值是从0开始的依次往后排的。也就是,第一个值是0,第二个是1,第三个是2…

    enum class Lights{
    red = 0,
    green = 1,
    yellow = 2
    };

    上面的效果和默认值是一样的。

    还有一种方法是可以给枚举值指定负数,比如-1,考虑下面的代码:

    enum class Lights{
    red = -1,
    green,
    yellow
    };

    需要注意的是,上面red指定为-1,green没有指定值,那么green就是默认0,yellow就是1,依次递增。

    不过这种命名方式多少有点不符合常理了,虽然语法上没有错,编译也不会报错,但是不建议这么用。就维持默认就行了。

    4.整形显式转换成枚举

    一个整数类型的值可以显式地转换成枚举类型。如果这个值属于枚举的基础类型的取值范围,则转换是有效的;否则,如果超出了合理的表示范围,则转换的结果是未定义的。考虑下面的例子:

        enum class Flag:char {x =1,y =2,z =4,e=8,f=127,g=128};
        Flag flag4 = static_cast<Flag>(5);
        Flag flag5 = static_cast<Flag>(999);

    char的取值范围是-128-127,f=127的值是没问题的,但是g=128的值会引发窄化转换错误,从而导致编译报错。

    再看下面的两个,虽然编译器不报错,但是5不是枚举里面的值,这么做失去意义;999严重超过char的取值范围,但是不会触发窄化转换的错误,导致未定义的行为。

    关闭

    用微信“扫一扫”