Перечисления
Перечисления
С++ позволяет с помощью перечисления объявлять набор поименованных констант аналогично тому, как это делается в C#. Предположим, что в программе требуется хранить названия дней недели:
enum DayOfWeek {
Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
};
Обычно это объявление располагается в заголовочном файле или даже внутри класса. Приведенное выше объявление на первый взгляд представляется эквивалентным следующим определениям констант:
const int Sunday = 0;
const int Monday = 1;
const int Tuesday = 2;
const int Wednesday = 3;
const int Thursday = 4;
const int Friday = 5;
const int Saturday = 6;
Применяя конструкцию перечисления, мы можем затем объявлять переменные или параметры типа DayOfWeek, и компилятор гарантирует возможность присваивания им только значений перечисления DayOfWeek. Например:
DayOfWeek day = Sunday;
Если нас мало волнует обеспечение защищенности типов, мы можем просто написать
int day = Sunday;
Обратите внимание на то, что при ссылке на константу Sunday из перечисления DayOfWeek мы пишем просто Sunday, а не DayOfWeek::Sunday.
По умолчанию компилятор назначает последовательные целочисленные значения константам перечисления, начиная с нуля. При необходимости можно назначить другие значения:
enum DayOfWeek {
Sunday = 628,
Monday = 616,
Tuesday = 735,
Wednesday = 932,
Thursday = 852,
Friday = 607,
Saturday = 845
};
Если значение не задается для элемента перечисления, этот элемент примет значение предыдущего элемента, увеличенное на 1. Перечисления иногда используются для объявления целочисленных констант, и в этих случаях перечислению обычно имя не задают:
enum {
FirstPort = 1024, MaxPorts = 32767
};
Другой областью применения перечислений является представление набора опций. Рассмотрим пример диалогового окна Find (поиск) с четырьмя переключателями, которые управляют алгоритмом поиска (применение шаблона поиска, учет регистра, поиск в обратном направлении и повторение поиска с начала документа). Это можно представить в виде перечисления, значения констант которого равны некоторой степени 2:
enum FindOption {
NoOptions = 0x00000000,
WildcardSyntax = 0x00000001,
CaseSensitive = 0x00000002,
SearchBackward = 0x00000004,
WrapAround = 0x00000008
};
Каждая опция часто называется «флажком». Флажки можно объединять при помощи логических поразрядных операторов | или |=:
int options = NoOptions;
if (wilcardSyntaxCheckBox->isChecked())
options |= WildcardSyntax;
if (caseSensitiveCheckBox->isChecked())
options |= CaseSensitive;
if (searchBackwardCheckBox->isChecked())
options |= SearchBackwardSyntax;
if (wrapAroundCheckBox->isChecked())
options |= WrapAround;
Проверить значение флажка можно при помощи логического поразрядного оператора &:
if (options & CaseSensitive) {
// поиск с учетом регистра
}
Переменная типа FindOption может содержать только один флажок в данный момент времени. Результат объединения нескольких флажков при помощи оператора | представляет собой обычное целое число. К сожалению, здесь не обеспечивается защищенность типа: компилятор не будет «жаловаться», если функция, которая должна принимать в качестве параметра типа int некую комбинацию опций FindOption, фактически получит Saturday. Qt использует класс QFlags<T> для обеспечения защищенности своих собственных типов флажков. Этот класс можно также применять при определении пользовательских типов флажков. Подробное описание класса QFlags<T> можно найти в онлайновой документации.