Visual C++.NET 2010开发实践:基于C++/CLI
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.4 C++/CLI枚举

1.4.1 枚举的定义

与标准C++中定义枚举的方式不同,C++/CLI通过enum class组合关键字定义枚举类型。例如:

        enum class Suit {Clubs, Diamonds, Hearts, Spades};

C++/CLI枚举类型的变量只能够被赋值为该枚举定义中的值。并且在访问该变量时,必须通过枚举类型名称限定当前使用的枚举值。例如:

        Suit suit = Suit::Diamonds;

然而需要注意的是,在C++/CLI枚举中定义的所有常量都是对象,而标准C++枚举中枚举值为基本数据类型的值。实际上,C++/CLI枚举中的值都默认是System::Int32类型的对象,其中封装了int类型的值。

另外,可以在C++/CLI程序中使用与标准C++枚举相同的语法,它们的行为将与在本地C++程序中的行为相同。本地C++枚举的语法在C++/CLI程序中得到了扩充,并允许显式地指定枚举常量的类型。但是,在C++/CLI程序中最好还是使用C++/CLI枚举。

【例1.7】 C++/CLI枚举的使用示例。定义一个枚举值,并将这些枚举值强制转换为与其对应的整型值并输出。代码如下:

        // Ex1_7.cpp : 主项目文件
        #include "stdafx.h"
        using namespace System;
        enum class Suit {Clubs, Diamonds, Hearts, Spades};
        int main(array<System::String ^> ^args)
        {
            Suit suit = Suit::Clubs;
            int value = safe_cast<int>(suit);
            Console::WriteLine(L"Suit为: {0},且值为: {1}", suit, value);
            suit = Suit::Diamonds;
            value = safe_cast<int>(suit);
            Console::WriteLine(L"Suit为: {0},且值为: {1}", suit, value);
            suit = Suit::Hearts;
            value = safe_cast<int>(suit);
            Console::WriteLine(L"Suit为: {0},且值为: {1}", suit, value);
            suit = Suit::Spades;
            value = safe_cast<int>(suit);
            Console::WriteLine(L"Suit为: {0},且值为: {1}", suit, value);
            return 0;
        }

当Ex1_7程序运行后,枚举中的每个常量都对应了一个常量值,其中第一个枚举常量默认值为0,而其他枚举常量的值依次递增。Ex1_7项目的运行结果如图1.11所示。

图1.11 Ex1_7项目的运行结果

1.4.2 枚举的常量

虽然C++/CLI枚举中的值都默认是System::Int32类型的对象,但是还可以将其指定为如表1.5所示的任意一种基本类型。

表1.5 C++/CLI枚举常量可用的数据类型

在指定枚举常量的类型时,可以在定义枚举的类型名称之后通过冒号(“:”)来说明常量的类型。例如,下面的代码将枚举中的常量指定为System::Char类型,那么其对应的基本类型为char类型。

        enum class Face : char { Ace, Two, Three, Four, Five, Six, Seven, Eight,
    Nine, Ten, Jack, Queen, King };

一般情况下,在指定枚举常量的类型后,枚举中第一个枚举常量的默认值为0,而后面的枚举常量依次递增。当然,也可以为枚举类型中的一个或全部枚举常量都指定对应的值。例如,如果将Face枚举中Acer常量指定为1,那么后面枚举常量的值将都依次加1。

        enum class Face1 : char { Ace=1, Two, Three, Four, Five, Six,
                                  Seven, Eight, Nine, Ten, Jack, Queen, King };
        enum class Face2 : char { Ace=14, Two=2, Three, Four, Five, Six,
                                  Seven, Eight, Nine, Ten, Jack,Queen,King};

1.4.3 枚举常量的运算

由于在定义C++/CLI枚举时为枚举常量指定了对应的值,所以可以对枚举常量进行各种运算(枚举常量类型为bool类型时除外)。

例如,可以通过“++”或“--”运算符对枚举常量进行递增或递减运算,从而改变枚举常量的值。但是,通过递增或递减后的枚举变量完全不会对运算结果进行有效性验证,因此需要在程序中确保其对应的枚举值。

        Face card = Face::Ten;         // card的值为Face::Ten
        card++;                         // card的值为Face::Jack

同时,还可以对枚举常量进行算术运算,如加、减、乘和除等。但是,不能直接将枚举常量与其他非枚举类型的常量进行运算,这是因为算术运算两端的操作数的类型不同,并且它们也不能自动转换成相同的类型,所以需要通过类型强制转换来进行算术运算。例如:

        card = card – Face::Two;           // card的值为Face::Eight
        card = card – safe_cast<Face>(2);  // card的值为Face::Six

同样,还可以通过关系运算符比较两个枚举常量的值,其比较结果将产生一个bool类型的值。例如:

        if (card < Face::Eight) Console::WriteLine(L"Card的值小于8点");
        if (card > Face::Eight) Console::WriteLine(L"Card的值大于8点");
        if (card != Face::Eight) Console::WriteLine(L"Card的值不等8点");
        if (card == Face::Eight) Console::WriteLine(L"Card的值等于8点");

另外,还可以将枚举定义成为标识位,这种标识位可用其中的某些位记录一种或多种事件。在将枚举定义成为表示标识位时,需要通过[Flags]属性修饰。其中,属性是添加到程序语句中的附加信息,用于指示编译器以何种方式修改代码或插入代码。例如,定一个枚举标识位的方式如下:

        [Flags]enum class FlagBits{Ready=1,ReadMode=2,WriteMode=4,EOF=8,Disable=16};

对于表示标识位的枚举常量,可以通过位运算符对这些常量进行运算。例如,可以使用或运算符(“|”)组合标识位,或者通过取反运算符(“~”)获得某个标识位取反的值。

        FlagBits status = FlagBits::Ready | FlagBits::ReadMode | FlagBits::EOF;
        status = status &~FlagBits::Ready;