C++ 枚举声明

C++ 枚举声明

Visual Studio 2013

枚举是用户定义的类型,其中包含一组称为枚举器的命名的整型常数。

说明 说明

本文包含 ISO 标准 C++ 语言 enum 类型和 C++11 中引入的范围(或强类型)enum class 类型。 有关 C++/CLI 和 C++/CX 中 public enum class 或 private enum class 类型的详细信息,请参阅 枚举类

//Unscoped enum:
enum [identifier] [: type]

{enum-list}; 

//Scoped enum:
enum [class|struct] 
[identifier] [: type] 
{enum-list};

identifier

指定给与枚举的类型名称。

type

枚举器的基础类型;所有枚举器都具有相同的基础类型。 可能是任何整型。

enum-list

枚举中以逗号分隔的枚举器列表。 范围中的每个枚举器或变量名必须是唯一的。 但是,值可以重复。 在未区分范围的枚举中,范围是周边范围;在区分范围的枚举中,范围是 enum-list 本身。

枚举提供上下文来描述以命名常数表示的一系列值,这些值也称为枚举器。 在原始 C 和 C++ 枚举类型中,非限定枚举器在声明枚举的整个范围中可见。 在区分范围的枚举中,枚举器名称必须由枚举类型名称限定。 以下示例演示两种枚举之间的基本差异:

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

    void PlayCard(Suit suit)
    {
        if (suit == Suit::Clubs) // Enumerator must be qualified by enum type
        { /*...*/}
    }
}

namespace CardGame_NonScoped
{
    enum Suit { Diamonds, Hearts, Clubs, Spades };

    void PlayCard(Suit suit)
    {
        if (suit == Clubs) // Enumerator is visible without qualification
        { /*...*/
        }
    }
}

将为枚举中的每个名称分配一个整数值,该值与其在枚举中的顺序相对应。 默认情况下,为第一个值分配 0,为下一个值分配 1,以此类推,但您可以显式设置枚举器的值,如下所示:

C++
enum Suit { Diamonds = 1, Hearts, Clubs, Spades };

为枚举器 Diamonds 分配值 1 后续枚举器接收的值会在前一个枚举器的值的基础上加一(如果没有显式赋值)。 在前面的示例中,Hearts 将具有值 2,Clubs 将具有值 3,依此类推。

每个枚举器将被视为常数,并且必须在定义 enum 的范围内(对于未区分围的枚举)或在枚举本身中(对于区分范围的枚举)具有唯一名称。 为这些名称指定的值不必是唯一的。 例如,如果一个未区分范围的枚举 Suit 的声明如下:

C++
enum Suit { Diamonds = 5, Hearts, Clubs = 4, Spades };

DiamondsHeartsClubs 和 Spades 的值分别是 5、6、4 和 5。 请注意,5 使用了多次;尽管这并不符合预期,但是允许的。 对于区分范围的枚举来说,这些规则是相同的。

强制转换规则

未区分范围的枚举常数可以隐式转换为 int,但是 int 不可以隐式转换为枚举值。 下面的示例显示了如果尝试为 hand 分配一个不是 Suit 的值可能出现的情况:

C++
int account_num = 135692;
Suit hand;
hand = account_num; // error C2440: '=' : cannot convert from 'int' to 'Suit'

将 int 转换为区分范围或未区分范围的枚举器时,需要强制转换。 但是,您可以将区分范围的枚举器提升为整数值,而不进行强制转换。

C++
int account_num = Hearts; //OK if Hearts is in a unscoped enum

按照这种方式使用隐式转换可能导致意外副作用。 若要帮助消除与区分范围的枚举相关的编程错误,区分范围的枚举值必须是强类型值。 区分范围的枚举器必须由枚举类型名称限定,并且无法隐式转换为 int 类型,如以下示例所示:

C++
namespace ScopedEnumConversions
{
    enum class Suit { Diamonds, Hearts, Clubs, Spades };
 
    void AttemptConversions()
    {
        Suit hand; 
        hand = Clubs; // error C2065: 'Clubs' : undeclared identifier
        hand = Suit::Clubs; //Correct.
        int account_num = 135692;
        hand = account_num; // error C2440: '=' : cannot convert from 'int' to 'Suit'
        hand = static_cast<Suit>(account_num); // OK, but probably a bug!!!

        account_num = Suit::Hearts; // error C2440: '=' : cannot convert from 'Suit' to 'int'
        account_num = static_cast<int>(Suit::Hearts); // OK
}

注意,hand = account_num; 行仍会导致对未区分范围的枚举发生的错误,如前面所示。 它可以与显式强制转换一起使用。 但是,借助区分范围的枚举,不再允许在没有显式强制转换的情况下在下一条语句 account_num = Suit::Hearts; 中尝试转换。

### C++ 枚举 (Enum) 的基本概念 在 C++ 中,`enum` 是一种用于定义一组命名整数常量的关键字。通过使用 `enum`,程序员可以提高代码的可读性和维护性,同时减少硬编码数值带来的错误。 #### 基本语法 以下是 C++枚举类型的声明方式: ```cpp enum EnumName { constant1, constant2, constant3 }; ``` 默认情况下,第一个枚举成员被赋值为 0,后续成员依次递增[^1]。然而,也可以显式指定每个成员的值: ```cpp enum Color { RED = 1, GREEN = 2, BLUE = 4 }; ``` #### 使用示例 下面是一个简单的例子展示如何定义和使用枚举类型: ```cpp #include <iostream> using namespace std; // 定义一个枚举类型 enum Weekday { Monday, Tuesday, Wednesday, Thursday, Friday }; int main() { Weekday day = Tuesday; // 使用枚举变量 switch(day) { case Monday: cout << "Today is Monday." << endl; break; case Tuesday: cout << "Today is Tuesday." << endl; break; default: cout << "Other days." << endl; } return 0; } ``` 上述代码展示了如何利用枚举简化条件判断逻辑并增强代码清晰度[^2]。 #### 强类型枚举 (Scoped Enums) 自 C++11 起引入了一种新的强类型枚举形式——scoped enums 或者 class-based enums。这种新形式提供了更好的作用域控制以及更强的安全保障。 ```cpp enum class Direction : char { Up = 'U', Down = 'D' }; void move(Direction dir){ if(dir == Direction::Up){ cout << "Moving up!" << endl; } } int main(){ Direction d = Direction::Down; move(d); return 0; } ``` 这里需要注意的是,在调用时必须加上枚举的名字作为缀以区分同的枚举项[^3]。 #### 解决常见问题 当处理涉及多个状态或者选项的选择场景下,采用合适的枚举设计能够有效降低复杂度并且提升程序健壮性。例如避免越界访问数组等问题可以通过合理设置枚举范围来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值