枚举(Enumeration)是C++中一种用户定义的数据类型,用于定义一组命名的常量。枚举提供了一种将相关常量组织在一起的方式,使代码更加可读和易于维护。

传统枚举(C风格枚举)

基本语法和使用

#include <iostream>
#include <string>
 
// 基本枚举定义
enum Color {
    RED,      // 默认值为 0
    GREEN,    // 默认值为 1
    BLUE,     // 默认值为 2
    YELLOW    // 默认值为 3
};
 
// 指定枚举值
enum Status {
    PENDING = 1,
    PROCESSING = 5,
    COMPLETED = 10,
    FAILED = -1
};
 
// 枚举在函数中的使用
std::string getColorName(Color color) {
    switch (color) {
        case RED:    return "红色";
        case GREEN:  return "绿色";
        case BLUE:   return "蓝色";
        case YELLOW: return "黄色";
        default:     return "未知颜色";
    }
}
 
void demonstrateBasicEnum() {
    std::cout << "=== 基本枚举示例 ===" << std::endl;
    
    // 声明和初始化
    Color myColor = RED;
    Status currentStatus = PROCESSING;
    
    std::cout << "颜色值: " << myColor << " (" << getColorName(myColor) << ")" << std::endl;
    std::cout << "状态值: " << currentStatus << std::endl;
    
    // 枚举值的比较
    if (myColor == RED) {
        std::cout << "这是红色!" << std::endl;
    }
    
    // 遍历枚举值
    std::cout << "所有颜色:" << std::endl;
    for (int i = RED; i <= YELLOW; ++i) {
        Color c = static_cast<Color>(i);
        std::cout << "  " << i << ": " << getColorName(c) << std::endl;
    }
}

传统枚举的问题

#include <iostream>
 
// 问题1: 名称污染
enum Animal {
    CAT,
    DOG,
    BIRD
};
 
enum Pet {
    // CAT,  // 错误!与上面的CAT冲突
    HAMSTER,
    FISH
};
 
// 问题2: 隐式转换为整数
void demonstrateProblems() {
    std::cout << "\n=== 传统枚举的问题 ===" << std::endl;
    
    Animal myAnimal = CAT;
    
    // 问题:可以隐式转换为整数
    int animalValue = myAnimal;  // 这是允许的,但可能不是我们想要的
    std::cout << "动物值: " << animalValue << std::endl;
    
    // 问题:可以与整数进行比较
    if (myAnimal == 0) {  // 这样的比较是允许的,但语义不清
        std::cout << "动物值等于0" << std::endl;
    }
    
    // 问题:可以进行算术运算
    Animal nextAnimal = static_cast<Animal>(myAnimal + 1);
    std::cout << "下一个动物值: " << nextAnimal << std::endl;
}

作用域枚举(C++11 强类型枚举)

基本语法

#include <iostream>
#include <string>
 
// 强类型枚举(enum class)
enum class Color {
    Red,
    Green,
    Blue,
    Yellow
};
 
enum class Status {
    Pending = 1,
    Processing = 5,
    Completed = 10,
    Failed = -1
};
 
// 指定底层类型
enum class Priority : char {
    Low = 'L',
    Medium = 'M',
    High = 'H',
    Critical = 'C'
};
 
// 枚举类的使用函数
std::string getColorName(Color color) {
    switch (color) {
        case Color::Red:    return "红色";
        case Color::Green:  return "绿色";
        case Color::Blue:   return "蓝色";
        case Color::Yellow: return "黄色";
    }
    return "未知颜色";
}
 
std::string getStatusName(Status status) {
    switch (status) {
        case Status::Pending:    return "等待中";
        case Status::Processing: return "处理中";
        case Status::Completed:  return "已完成";
        case Status::Failed:     return "失败";
    }
    return "未知状态";
}
 
void demonstrateScopedEnum() {
    std::cout << "\n=== 强类型枚举示例 ===" << std::endl;
    
    // 必须使用作用域限定符
    Color myColor = Color::Red;
    Status currentStatus = Status::Processing;
    Priority taskPriority = Priority::High;
    
    std::cout << "颜色: " << getColorName(myColor) << std::endl;
    std::cout << "状态: " << getStatusName(currentStatus) << std::endl;
    std::cout << "优先级: " << static_cast<char>(taskPriority) << std::endl;
    
    // 强类型枚举不会隐式转换为整数
    // int colorValue = myColor;  // 错误!不能隐式转换
    int colorValue = static_cast<int>(myColor);  // 必须显式转换
    std::cout << "颜色的整数值: " << colorValue << std::endl;
    
    // 不同枚举类型之间不能直接比较
    // if (myColor == currentStatus) {}  // 错误!类型不匹配
    
    // 同一枚举类型的比较
    if (myColor == Color::Red) {
        std::cout << "这是红色!" << std::endl;
    }
}

枚举类的高级特性

#include <iostream>
#include <unordered_map>
#include <vector>
#include <type_traits>
 
// 带有方法的枚举类包装
class ColorUtils {
public:
    enum class Color {
        Red,
        Green,
        Blue,
        Yellow,
        Purple,
        Orange
    };
    
    // 获取颜色名称
    static std::string getName(Color color) {
        static const std::unordered_map<Color, std::string> colorNames = {
            {Color::Red, "红色"},
            {Color::Green, "绿色"},
            {Color::Blue, "蓝色"},
            {Color::Yellow, "黄色"},
            {Color::Purple, "紫色"},
            {Color::Orange, "橙色"}
        };
        
        auto it = colorNames.find(color);
        return (it != colorNames.end()) ? it->second : "未知颜色";
    }
    
    // 获取RGB值
    static std::tuple<int, int, int> getRGB(Color color) {
        switch (color) {
            case Color::Red:    return {255, 0, 0};
            case Color::Green:  return {0, 255, 0};
            case Color::Blue:   return {0, 0, 255};
            case Color::Yellow: return {255, 255, 0};
            case Color::Purple: return {128, 0, 128};
            case Color::Orange: return {255, 165, 0};
        }
        return {0, 0, 0};
    }
    
    // 获取所有颜色
    static std::vector<Color> getAllColors() {
        return {
            Color::Red, Color::Green, Color::Blue,
            Color::Yellow, Color::Purple, Color::Orange
        };
    }
    
    // 检查是否为暖色调
    static bool isWarmColor(Color color) {
        return color == Color::Red || 
               color == Color::Yellow || 
               color == Color::Orange;
    }
    
    // 混合两种颜色(简化版)
    static Color mixColors(Color color1, Color color2) {
        if ((color1 == Color::Red && color2 == Color::Blue) ||
            (color1 == Color::Blue && color2 == Color::Red)) {
            return Color::Purple;
        }
        if ((color1 == Color::Red && color2 == Color::Yellow) ||
            (color1 == Color::Yellow && color2 == Color::Red)) {
            return Color::Orange;
        }
        // 其他组合返回第一种颜色
        return color1;
    }
};
 
// 枚举迭代器
template<typename EnumType>
class EnumIterator {
private:
    using UnderlyingType = std::underlying_type_t<EnumType>;
    UnderlyingType current;
    UnderlyingType end;
    
public:
    EnumIterator(EnumType start, EnumType finish) 
        : current(static_cast<UnderlyingType>(start))
        , end(static_cast<UnderlyingType>(finish)) {}
    
    EnumType operator*() const {
        return static_cast<EnumType>(current);
    }
    
    EnumIterator& operator++() {
        ++current;
        return *this;
    }
    
    bool operator!=(const EnumIterator& other) const {
        return current <= end;
    }
    
    EnumIterator begin() const {
        return *this;
    }
    
    EnumIterator end() const {
        EnumIterator endIter = *this;
        endIter.current = end + 1;
        return endIter;
    }
};
 
void demonstrateAdvancedEnum() {
    std::cout << "\n=== 高级枚举特性示例 ===" << std::endl;
    
    using Color = ColorUtils::Color;
    
    // 使用枚举工具类
    Color myColor = Color::Red;
    std::cout << "颜色: " << ColorUtils::getName(myColor) << std::endl;
    
    auto [r, g, b] = ColorUtils::getRGB(myColor);
    std::cout << "RGB值: (" << r << ", " << g << ", " << b << ")" << std::endl;
    
    std::cout << "是暖色调吗: " << (ColorUtils::isWarmColor(myColor) ? "是" : "否") << std::endl;
    
    // 颜色混合
    Color mixedColor = ColorUtils::mixColors(Color::Red, Color::Blue);
    std::cout << "红色 + 蓝色 = " << ColorUtils::getName(mixedColor) << std::endl;
    
    // 遍历所有颜色
    std::cout << "\n所有颜色及其RGB值:" << std::endl;
    for (Color color : ColorUtils::getAllColors()) {
        auto [r, g, b] = ColorUtils::getRGB(color);
        std::cout << "  " << ColorUtils::getName(color) 
                  << ": RGB(" << r << ", " << g << ", " << b << ")" << std::endl;
    }
    
    // 使用枚举迭代器
    std::cout << "\n使用迭代器遍历颜色:" << std::endl;
    EnumIterator<Color> colorRange(Color::Red, Color::Orange);
    for (auto it = colorRange.begin(); it != colorRange.end(); ++it) {
        std::cout << "  " << ColorUtils::getName(*it) << std::endl;
    }
}

枚举在实际项目中的应用

状态机实现

#include <iostream>
#include <string>
#include <functional>
#include <unordered_map>
 
// 游戏角色状态机
class GameCharacter {
public:
    enum class State {
        Idle,
        Walking,
        Running,
        Jumping,
        Attacking,
        Defending,
        Dead
    };
    
    enum class Event {
        StartWalk,
        StartRun,
        Jump,
        Attack,
        Defend,
        Stop,
        TakeDamage,
        Die
    };
    
private:
    State currentState;
    std::string name;
    int health;
    
    // 状态转换表
    std::unordered_map<State, std::unordered_map<Event, State>> transitions;
    
    // 状态进入处理函数
    std::unordered_map<State, std::function<void()>> stateHandlers;
    
public:
    GameCharacter(const std::string& characterName) 
        : name(characterName), currentState(State::Idle), health(100) {
        setupTransitions();
        setupStateHandlers();
    }
    
    void setupTransitions() {
        // 从Idle状态的转换
        transitions[State::Idle][Event::StartWalk] = State::Walking;
        transitions[State::Idle][Event::StartRun] = State::Running;
        transitions[State::Idle][Event::Jump] = State::Jumping;
        transitions[State::Idle][Event::Attack] = State::Attacking;
        transitions[State::Idle][Event::Defend] = State::Defending;
        
        // 从Walking状态的转换
        transitions[State::Walking][Event::Stop] = State::Idle;
        transitions[State::Walking][Event::StartRun] = State::Running;
        transitions[State::Walking][Event::Jump] = State::Jumping;
        transitions[State::Walking][Event::Attack] = State::Attacking;
        
        // 从Running状态的转换
        transitions[State::Running][Event::Stop] = State::Idle;
        transitions[State::Running][Event::StartWalk] = State::Walking;
        transitions[State::Running][Event::Jump] = State::Jumping;
        transitions[State::Running][Event::Attack] = State::Attacking;
        
        // 从Jumping状态的转换
        transitions[State::Jumping][Event::Stop] = State::Idle;
        
        // 从Attacking状态的转换
        transitions[State::Attacking][Event::Stop] = State::Idle;
        
        // 从Defending状态的转换
        transitions[State::Defending][Event::Stop] = State::Idle;
        
        // 死亡转换(从任何状态)
        for (auto& stateMap : transitions) {
            stateMap.second[Event::Die] = State::Dead;
        }
    }
    
    void setupStateHandlers() {
        stateHandlers[State::Idle] = [this]() {
            std::cout << name << " 进入待机状态" << std::endl;
        };
        
        stateHandlers[State::Walking] = [this]() {
            std::cout << name << " 开始行走" << std::endl;
        };
        
        stateHandlers[State::Running] = [this]() {
            std::cout << name << " 开始奔跑" << std::endl;
        };
        
        stateHandlers[State::Jumping] = [this]() {
            std::cout << name << " 跳跃中" << std::endl;
        };