c++ 使用枚举作为数组索引

v440hwme  于 2023-06-25  发布在  其他
关注(0)|答案(8)|浏览(230)

我有这个枚举:

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语句的枚举。使用枚举作为数组索引感觉不对。)
1.我必须指定枚举的值吗?默认情况下,它似乎从0开始,递增1,但它能保证在所有编译器中都能以这种方式工作吗?

iezvtpos

iezvtpos1#

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

我想是的。我经常做同样的事情。
”””有一个更好的方法来做吗?***

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 值。如果你把这些值作为 * int * 传递,这不是一个大问题。但是,如果你真的想要一个 Button::State,麻烦了。

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

没关系,只要**记录下来,下一个人就知道发生了什么!(这就是评论的目的)。

是否必须指定枚举的值?

如果没有'='赋值,枚举的 * 应该 * 从零开始并向上递增。
如果枚举项具有“=”赋值,则后续非“=”枚举项将从此处继续计数。
来源:* 注解C++参考手册 *,第113页
也就是说,我喜欢指定初始值,只是为了让代码更加清晰。

zsbz8rwp

zsbz8rwp2#

是的,它会工作得很好。也就是说,在任何情况下,你 * 真的 * 应该在你的枚举中放入另一个条目来定义项目数量的值:

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

然后你可以像这样定义数组

Color colors[STATE_COUNT];

否则,要保持状态数量与数组大小同步就很麻烦了。如果没有初始化,枚举将始终从零开始,然后如果没有初始化,则每个附加项将被分配一个比前一项大一的值。当然,如果你愿意的话,显式地加一个零也不会有什么坏处。如果您不介意编写额外的代码,我会使用如下函数 Package 对原始数组的访问

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

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

rseugnpd

rseugnpd3#

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

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

fjnneemd4#

风格方面,还不错。
Delphi 等基于Pascal的语言允许将数组边界指定为枚举类型,因此您只能使用该特定类型的项作为索引。

vhmi4jdf

vhmi4jdf5#

问题1:我认为这是一种很好的编程风格。我一直都在用问题二:据我所知,它保证以这种方式工作,所以你不必指定值。
我也会把NUM_BUTTON_STATES放到枚举中。

t5zmwmid

t5zmwmid6#

使用枚举来索引数组是完全正常的。
您不必指定每个枚举值,它们将自动递增1。让编译器选择值可以减少输入错误和创建bug的可能性,但这会剥夺您看到值的可能性,这在调试中可能很有用。

trnvg8h3

trnvg8h37#

这很好,但我想对数组进行一些边界检查,如果有人添加了另一个ButtonState,您就会遇到问题。
而且,colors数组的元素是不可变的,所以也许可以考虑使用不同的集合来数组,这样你就可以强制这种不可变性。也许是Dictionary<ButtonState,ButtonColor>

du7egjpx

du7egjpx8#

其中一种方法是在类中创建一个内部向量并覆盖运算符[]:(here is the link to online code

#include <iostream>
#include <vector>

template<typename DATA_TYPE, typename INDEX_TYPE>
class MyVector
{
protected:
    std::vector<DATA_TYPE> pp;

public:    
    template<typename ... ARGS>
    MyVector(ARGS ... args): pp{args...} {};

    DATA_TYPE& operator[](INDEX_TYPE x) { 
        return pp[static_cast<size_t>(x)];
    };

    auto size() const { return pp.size(); }

    // implement other menthods

};

enum class EWeekDays{
    SUN, MON, TUE, WED, THU, FRI, SAT
};

int main()
{
    MyVector<int, EWeekDays> q{2,3,4,5};

    std::cout << q[EWeekDays::MON] << "\n";

    return 0;
}

相关问题