Использование перечисления в качестве индекса массива
у меня есть это перечисление:
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] чтобы получить цвета для любого состояния, в котором находится кнопка.
мои вопросы:
- это хороший стиль программирования? Есть ли лучший способ сделать это? (Я обычно использую только перечисления с операторами switch... использование перечисления в качестве индекса массива не кажется правильным.)
- Я есть to укажите значения перечисления? Кажется, что он начинается с 0 по умолчанию и увеличивается на 1, но гарантировано ли это работает во всех компиляторах?
7 ответов:
это хороший стиль программирования?
Я так думаю. Я делаю то же самое довольно часто.
есть ли лучший способ сделать это?
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 сейчас действует Кнопка:: State значение. Не большая проблема, если вы передаете эти значения как ints. Но проблема, если вы на самом деле ожидаете Кнопка:: State.
использование перечисления в качестве индекса массива не кажется правильным.
Это нормально. Просто документ это, так что следующий парень знает, что происходит! (Вот для чего нужны комментарии.)
должен ли я указывать значения перечисления?
без ' = ' назначения, перечисления должны начать с нуля и увеличивается.
Если запись перечисления имеет ' = 'присвоенное значение, последующие не' = ' записи перечисления продолжают отсчет оттуда.
источник: Аннотированное Справочное Руководство По C++, стр. 113
тем не менее, мне нравится указывать начальное значение, чтобы сделать код намного яснее.
Да, это будет работать хорошо. Тем не менее, в любом случае, вы действительно следует поставить другую запись в вашем перечислении, определяющую значение количества элементов:
enum ButtonState { BUTTON_NORMAL, BUTTON_PRESSED, BUTTON_CLICKED, STATE_COUNT };затем вы можете определить массив как
Color colors[STATE_COUNT];в противном случае, это беспорядок, чтобы сохранить количество состояний синхронно с размером массива. Перечисления всегда будут начинаться с нуля, если не инициализированы иначе, а затем каждой дополнительной записи будет присвоено значение на единицу выше предыдущий, если не инициализирован иным образом. Конечно, это также не повредит, если вы поставите ноль явно, если хотите. Если вы не возражаете против дополнительного кода, я бы обернул доступ к необработанному массиву с помощью функции, такой как
Color & operator[](ButtonState state) { return array[state]; }или эквивалент
getColorфункция переадресации запроса. Это запретило бы напрямую индексировать массив с некоторым целым числом, которое почти наверняка в какой-то момент потерпит неудачу, потому что один получает индексы неправильно.
использование перечисления в порядке. Но вам не нужно указывать значения для каждого элемента. Достаточно указать первое значение. Я бы не предположил, что перечисления начинаются с 0, потому что я использовал компиляторы, которые использовали 1 в качестве начального значения (не для ПК, но некоторые компиляторы для микроконтроллеров имеют какое-то странное поведение). Кроме того, вы можете избавиться от const:
enum ButtonState { BUTTON_NORMAL = 0, BUTTON_PRESSED, BUTTON_CLICKED, NUM_BUTTON_STATES };
Вопрос 1: я думаю, что это хороший стиль программирования. Я использую его все время. Вопрос 2: Насколько я знаю, он гарантированно работает таким образом, поэтому вам не нужно указывать значения.
и я бы поставил NUM_BUTTON_STATES в перечисление, а также.
стиль-мудрый, это просто прекрасно.
языки на основе Паскаля, такие как Delphi, позволяют указывать границы массива как тип перечисления, поэтому вы можете использовать только элементы этого конкретного типа в качестве индекса.
совершенно нормально использовать перечисление для индексирования в массив.
вам не нужно указывать каждое значение перечисления, они будут автоматически увеличиваться на 1. Разрешение компилятору выбирать значения уменьшает возможность опечатки и создания ошибки, но лишает вас возможности видеть значения, которые могут быть полезны при отладке.
это нормально, но я хотел бы сделать некоторые проверки границ массива, как будто кто-то добавляет еще один ButtonState, у вас будет проблема.
кроме того, элементы массива colors неизменяемы, поэтому, возможно, посмотрите на использование другой коллекции для массива, чтобы вы могли обеспечить эту неизменность. Может быть, a
Dictionary<ButtonState,ButtonColor>
Comments