使用枚举作为数组索引

时间:2008-12-31 23:02:54

标签: c++ enums

我有这个枚举:

enum ButtonState {
    BUTTON_NORMAL = 0,
    BUTTON_PRESSED = 1,
    BUTTON_CLICKED = 2
};

const u8 NUM_BUTTON_STATES = 3;

在我的Button类中,我有成员变量ButtonState state;ButtonColors colors[NUM_BUTTON_STATES];。在绘制按钮时,我使用colors[state]来获取按钮所处状态的颜色。

我的问题:

  1. 这是一种很好的编程风格吗?有没有更好的方法呢? (我通常只使用带有switch语句的枚举...使用枚举作为数组索引感觉不对。)
  2. 来指定枚举的值吗?它似乎默认从0开始并递增1,但它是否保证在所有编译器中以这种方式工作?

7 个答案:

答案 0 :(得分:47)

这是一种很好的编程风格吗?

我是这么认为的。我经常做同样的事情。

有没有更好的方法呢?

class Button
{
public:
    // Used for array indexes!  Don't change the numbers!
  enum State {
    NORMAL = 0,
    PRESSED,
    CLICKED,
    NUMBER_OF_BUTTON_STATES
  };
};

缺点是 NUMBER_OF_BUTTON_STATES 现在是一个有效的 Button :: State 值。如果您将这些值作为 ints 传递,则不是一个大问题。但是,如果您实际上期待 Button :: State

,则会遇到麻烦

使用枚举作为数组索引感觉不对。

没关系。只是 DOCUMENT 它,所以下一个人知道发生了什么! (这就是评论的用途。)

我是否必须指定枚举值?

如果没有'='赋值,枚举的应该从零开始并向上递增。

如果枚举条目的值为'=',则后续的非'='枚举条目将从那里继续计数。

来源: Annotated C ++参考手册,第113页

那就是说,我想指定初始值只是为了使代码更清晰。

答案 1 :(得分:23)

是的,它会运作良好。也就是说,无论如何,你确实应该在枚举中添加另一个条目来定义项目数量的值:

enum ButtonState {
    BUTTON_NORMAL,
    BUTTON_PRESSED,
    BUTTON_CLICKED,
    STATE_COUNT
};

然后你可以像

那样定义数组
Color colors[STATE_COUNT];

否则,保持状态量与数组大小同步是一件麻烦事。如果没有以其他方式初始化,枚举将始终从零开始,然后如果没有以其他方式初始化,则每个附加条目将被分配一个高于前一个的值。当然,如果你想要明确地设置零,也不会受到伤害。如果您不介意其他代码,我会使用像

这样的函数包装对原始数组的访问
Color & operator[](ButtonState state) {
    return array[state];
}

或转发请求的等效getColor函数。那将禁止直接用一些整数索引数组,这几乎肯定会在某些时候因为索引错误而失败。

答案 2 :(得分:15)

使用枚举是可以的。但您不必为每个项目指定值。足以指定第一个值。我不认为枚举从0开始,因为我使用的编译器使用1作为起始值(不是用于PC而是用于微控制器的某些编译器有一些奇怪的行为)。 另外,你可以摆脱const:

enum ButtonState {
    BUTTON_NORMAL = 0,
    BUTTON_PRESSED,
    BUTTON_CLICKED,
    NUM_BUTTON_STATES
};

答案 3 :(得分:3)

问题1:我认为这是一种很好的编程风格。我用它所有的时间。 问题2:据我所知,保证以这种方式工作,因此您不必指定值。

我也会将NUM_BUTTON_STATES列入枚举。

答案 4 :(得分:3)

风格方面,它很好。

像Delphi这样基于Pascal的语言允许将数组边界指定为枚举类型,因此您只能将该特定类型的项目用作索引。

答案 5 :(得分:1)

使用枚举来索引数组是完全正常的。

您不必指定每个枚举值,它们将自动增加1.让编译器选择值可以减少错误输入和创建错误的可能性,但是它会使您无法看到可能有用的值在调试中。

答案 6 :(得分:1)

没关系,但是我想对数组进行一些检查,好像有人添加了另一个ButtonState,你就会遇到问题。

此外,colors数组的元素是不可变的,因此可以考虑使用不同的数组集合,以便您可以强制执行不变性。也许是Dictionary<ButtonState,ButtonColor>