正确使用枚举C ++

时间:2011-02-27 11:37:15

标签: c++ enums bit-manipulation

我一直在努力学习如何在C ++中正确使用枚举,而我几乎无法理解如何处理它们。我做了一个简单的程序,使用枚举和按位操作来改变交通信号灯:

    #include <iostream>

enum lights
{
    green = 1,
    yellow = 2,
    red = 4,
    control = 7
};

std::string change_light (std::string choice)
{
    lights light;
    int changed;

    if (choice == "yellow")
        light = yellow;

    else if (choice == "red")
        light = red;

    else if (choice == "green")
        light = green;

    changed = control & light;

    if (changed == red)
        return "red";

    else if (changed == yellow)
        return "yellow";

    else if (changed == green)
        return "green";
}

int main()
{   
    std::string choice = "";

    while (1)
    {
        std::cout << "What light do you want to turn on?" << std::endl;
        std::cin >> choice;
        std::cout << "Changed to " << change_light(choice) << std::endl;
    }

    return 0;
}

如何在保持按位操作和枚举的使用的同时改进该程序?如果你能告诉我如何改进它,它将极大地提高我对如何正确使用枚举的理解。

谢谢:D

3 个答案:

答案 0 :(得分:5)

枚举背后的整个想法是,您可以定义一组常量,为用户和编译器提供有关如何使用变量的一些提示。

如果change_light函数会采用这样的灯参数,那么你的例子会更有意义:

std::string change_light (lights choice)
{
    switch(choice)
    {
    case red: return "red";
    case yellow: return "yellow";
    case green: return "green";
    }
}

这样编译器知道,该函数只接受某些参数而你没有得到像change_light(“blue”)这样的函数调用


因此,您使用枚举来保护代码的其余部分免受错误的参数值的影响。你不能直接从std :: in读取枚举,因为它对你的枚举一无所知。阅读后,您应该将输入转换为枚举。像这样:

lights string_to_ligths(std::string choice)
{
    if(choice == "red") return red;
    if(choice == "yellow") return yellow;
    if(choice == "green") return green;
}

此处所有与红绿灯相关的功能仅接受枚举值,无需检查请求值是否在有效范围内。

答案 1 :(得分:2)

枚举只是具有有限有效值范围的整数。

让我们假设您将使用int:

实现您的信号量
#define SEMAPHORE_STATE_RED 1
#define SEMAPHORE_STATE_YELLOW 2
#define SEMAPHORE_STATE_GREEN 3
int semaphore_state;

以下内容会很好,但它会破坏您的信号量的语义:

semaphore_state = 10;
带有枚举的

它不会通过,编译器会捕获错误。

如果你使用switch而不是if / else:

,这个更大
switch (state)
{
    case SEMAPHORE_STATE_GREEN: /* bla */ break;
    case SEMAPHORE_STATE_RED: /* bla */ break;
    /* if state would be enum, compiler would catch that we are missing the SEMAPHORE_STATE_YELLOW case */
}

当然还有枚举的其他用途。例如,我个人更喜欢枚举常量而不是定义(从不实际使用枚举类型本身)。这个案例也是唯一可以与按位操作共存的麻烦。

答案 2 :(得分:1)

您似乎认为与枚举类型相关联的数字很重要。事实上,这些数字并不重要。枚举类型的真实想法是整齐地捕获一个变量,该变量具有数字的一组状态,并且通过使用字符(例如,纸牌套装,指南针)也很难捕获一周的方向或日期)。如果有的话,很少会为任何枚举值分配一个特定的数字 - 它是一个不属于枚举类型点的设施(但它偶尔会有用,所以它被保留)并且更容易混淆最初的程序员而不是协助,不应该被设想为枚举的一个组成部分 - 有些语言甚至不允许它(例如Modula-3,Haskell,Ocaml)。枚举类型并不经常使用 - 它们的使用有点模糊,它们通常不常用:它们增加了程序的清晰度而不是功率(与例如 if 语句形成对比,没有编程会几乎不可能!)并且实际上从来没有需要。这意味着您编写的代码片段虽然显示了正在使用的枚举类型,但并未证明其有用性:枚举类型在澄清某些较大程序的某个方面时非常有用,这一用法不易被证明。开始的程序员最好忽略它们,因为它们对于初学者来说似乎毫无意义和困惑。这是因为他们的目的很难证明 - 尽管它们很有用,但我向你保证!我再说一遍:他们提供清晰的表达,而不是力量。