使用枚举作为数组索引

Jer*_*ten 56 c++ enums

我有这个枚举:

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

const u8 NUM_BUTTON_STATES = 3;
Run Code Online (Sandbox Code Playgroud)

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

我的问题:

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

Mr.*_*Ree 49

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

我认同.我经常做同样的事情.

有没有更好的方法呢?

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

缺点是NUMBER_OF_BUTTON_STATES现在是一个有效的Button :: State值.如果您将这些值作为整数传递,那么这不是一个大问题.但是如果你真的期待一个Button :: State会有麻烦.

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

没关系.只要文件,所以未来的家伙知道是怎么回事!(这就是评论的内容.)

我必须指定枚举的值吗?

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

如果枚举条目具有'='赋值,则后续非'='枚举条目将从那里继续计数.

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

也就是说,我喜欢指定初始值只是为了使代码更清晰.

  • @Patrick Johnmeyer,你能说出那个特定的编译器吗? (4认同)
  • +1使用最后一个额外的枚举器作为大小:) (4认同)
  • 您应该使用命名空间而不是空类.它更准确地符合您的意图. (2认同)
  • C和C++语言标准指定枚举中的第一个枚举常量值为零,除非您为其分配不同的值.任何不这样做的编译器显然都是不合规的. (2认同)
  • ChrisN是对的,但遗憾的是我和这样的编译器一起工作 - 并且在过去的10年里,并没有减少.如果您对交叉编译器兼容性有任何疑虑,请指定零. (2认同)
  • 我之前的工作是使用三种不同的编译器来处理不同的目标,所以我可能会记错 - 但我相信它是Green Hills C++编译器的特定版本.如果没有设置,第一个值可以是任何值; 它基本上好像编译器使用未初始化的变量作为第一个值. (2认同)

Joh*_*itb 23

是的,它会运作良好.也就是说,在任何情况下,你真的应该在枚举中添加另一个条目来定义项目数量的值:

enum ButtonState {
    BUTTON_NORMAL,
    BUTTON_PRESSED,
    BUTTON_CLICKED,
    STATE_COUNT
};
Run Code Online (Sandbox Code Playgroud)

然后你可以定义数组

Color colors[STATE_COUNT];
Run Code Online (Sandbox Code Playgroud)

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

Color & operator[](ButtonState state) {
    return array[state];
}
Run Code Online (Sandbox Code Playgroud)

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


Ste*_*fan 15

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

enum ButtonState {
    BUTTON_NORMAL = 0,
    BUTTON_PRESSED,
    BUTTON_CLICKED,
    NUM_BUTTON_STATES
};
Run Code Online (Sandbox Code Playgroud)

  • 你有效地说'你不应该让编制者做标准要求他们做的事',这不是根本不好的建议.除非另有说明,否则标准要求`enum从0开始,程序员不应该羞于利用它 - 或找到一个称职的编译器. (4认同)

Rod*_*ddy 5

从风格上来说,还是不错的。

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