简体   繁体   English

使用枚举作为数组索引

[英]Using an enum as an array index

I have this enum: 我有这个枚举:

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

const u8 NUM_BUTTON_STATES = 3;

In my Button class I have member variables ButtonState state; 在我的Button类中,我有成员变量ButtonState state; and ButtonColors colors[NUM_BUTTON_STATES]; ButtonColors colors[NUM_BUTTON_STATES]; . When drawing the button, I use colors[state] to get the colours for whatever state the button is in. 在绘制按钮时,我使用colors[state]来获取按钮所处状态的颜色。

My questions: 我的问题:

  1. Is this good programming style? 这是一种好的编程风格吗? Is there a better way to do it? 有没有更好的方法呢? (I usually only use enums with switch statements... using an enum as an array index doesn't feel right.) (我通常只使用带有switch语句的枚举...使用枚举作为数组索引感觉不对。)
  2. Do I have to specify the values of the enum? 必须指定枚举的值吗? It seems to start from 0 by default and increment by 1 but is it guaranteed to work that way in all compilers? 它似乎默认从0开始并递增1,但它是否保证在所有编译器中以这种方式工作?

Is this good programming style? 这是一种好的编程风格吗?

I think so. 我认同。 I do the same thing quite frequently. 我经常做同样的事情。

Is there a better way to do it? 有没有更好的方法呢?

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

Drawback is that NUMBER_OF_BUTTON_STATES is now a valid Button::State value. 缺点是NUMBER_OF_BUTTON_STATES现在是一个有效的Button :: State值。 Not a big issue if you are passing these values around as ints . 如果您将这些值作为整数传递,那么这不是一个大问题。 But trouble if you are actually expecting a Button::State . 但是如果你真的期待一个Button :: State会有麻烦。

Using an enum as an array index doesn't feel right. 使用枚举作为数组索引感觉不对。

It's fine. 没关系。 Just DOCUMENT it, so the next guy knows what's going on! 只要文件 ,所以未来的家伙知道是怎么回事! (That's what comments are for.) (这就是评论的内容。)

Do I have to specify the values of the enum? 我必须指定枚举的值吗?

With no '=' assignment, enum's are supposed to start at zero and increment upwards. 没有'='赋值,枚举应该从零开始并向上递增。

If a enum entry has an '=' assigned value, subsequent non '=' enum entries continue counting from there. 如果枚举条目具有'='赋值,则后续非'='枚举条目将从那里继续计数。

Source: The Annotated C++ Reference Manual , pg 113 来源: Annotated C ++参考手册 ,第113页

That said, I like to specify the initial value just to make the code that much clearer. 也就是说,我喜欢指定初始值只是为了使代码更清晰。

Yeah it will work well. 是的,它会运作良好。 That said, in any case, you really should put another entry in your enumeration defining the value of the amount of items: 也就是说,在任何情况下,你真的应该在枚举中添加另一个条目来定义项目数量的值:

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

Then you can define the array like 然后你可以像这样定义数组

Color colors[STATE_COUNT];

otherwise, it's a mess to keep the amount of states synchronous with the size of the array. 否则,保持状态量与数组大小同步是一件麻烦事。 Enumerations will always start with zero if not otherwise initialized, and then each additional entry will be assigned a value one above the previous one, if not otherwise initialized. 如果没有以其他方式初始化,枚举将始终从零开始,然后如果没有以其他方式初始化,则每个附加条目将被分配一个高于前一个的值。 Of course it also wouldn't hurt if you put a zero explicitly if you want. 当然,如果你想要明确地设置零,也不会受到伤害。 If you don't mind additional code, i would wrap the access to the raw array using a function like 如果您不介意其他代码,我会使用像这样的函数包装对原始数组的访问

Color & operator[](ButtonState state) {
    return array[state];
}

Or an equivalent getColor function forwarding the request. 或者等效的getColor函数转发请求。 That would forbid directly indexing the array with some integer, which would almost certainly at some point fail because one gets the indexes wrong. 那将禁止直接用一些整数索引数组,这几乎肯定会在某些时候因为索引错误而失败。

Using an enum is ok. 使用枚举是可以的。 But you don't have to specify values for every item. 但您不必为每个项目指定值。 It's enough to specify the first value. 足以指定第一个值。 I wouldn't assume that enums start at 0, because I've used compilers which used 1 as the starting value (not for PCs but some compilers for microcontrollers have some weird behavior). 我不认为枚举从0开始,因为我使用的编译器使用1作为起始值(不是用于PC而是用于微控制器的某些编译器有一些奇怪的行为)。 Also, you could get rid of the const: 另外,你可以摆脱const:

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

Question 1: I think it's good programming style. 问题1:我认为这是一种很好的编程风格。 I use it all the time. 我用它所有的时间。 Question 2: As far as I know, it is guaranteed to work that way, so you don't have to specify the values. 问题2:据我所知,它保证以这种方式工作,因此您不必指定值。

And I would put NUM_BUTTON_STATES into the enum as well. 我也会将NUM_BUTTON_STATES列入枚举。

Style-wise, it's just fine. 风格方面,它很好。

Pascal-based languages like Delphi allow array bounds to be specified as an enum type, so you can only use items of that specific type as an index. 像Delphi这样的基于Pascal的语言允许将数组边界指定为枚举类型,因此您只能使用该特定类型的项作为索引。

It is perfectly normal to use an enum for indexing into an array. 使用枚举来索引数组是完全正常的。

You don't have to specify each enum value, they will increment automatically by 1. Letting the compiler pick the values reduces the possibility of mistyping and creating a bug, but it deprives you of seeing the values, which might be useful in debugging. 您不必指定每个枚举值,它们将自动增加1.让编译器选择值可以减少错误输入和创建错误的可能性,但是它使您无法看到可能在调试中有用的值。

It's fine, but I'd want to do some bounds checking on the array, as if someone adds another ButtonState, you'll have a problem. 这很好,但是我想对数组进行一些检查,好像有人添加了另一个ButtonState,你就会遇到问题。

Also, the elements of the colors array are immutable, so maybe look at using a different collection to array so that you can enforce that immutability. 此外,colors数组的元素是不可变的,因此可以考虑使用不同的数组集合,以便您可以强制执行不变性。 Maybe a Dictionary<ButtonState,ButtonColor> 也许是Dictionary<ButtonState,ButtonColor>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM