Перечисления в языке C++
Перечисление или перечисляемый тип - это тип данных, где любое значение (перечислитель) определяется как символьная константа.
Объявляется перечисляемый тип с помощью ключевого слова enum.
// Объявление перечисляемого типа enum Level { LEVEL_LOW, LEVEL_MEDIUM, LEVEL_HIGH }; Level level = LEVEL_MEDIUM; // Объявление и инициализация переменной перечисляемого типа
Все перечисления и перечислители находятся в одном пространстве имен, поэтому повторение перечислителей не допускается.
// Объявление перечисляемого типа enum SoundLevel { LOW, MEDIUM, HIGH }; enum BrightLevel { LOW, MEDIUM, HIGH }; // Ошибка
Значения перечислителей - это целые числа, присваиваемые в зависимости от позиции перечислителя в списке значений. Присваиание начинается с нуля.
enum Level { LEVEL_LOW, // значение 0 LEVEL_MEDIUM, // значение 1 LEVEL_HIGH // значение 2 };
Можно указывать значения перечислителей самостоятельно. В этом случае любые не определенные перечислители будут иметь значения на единицу больше, чем значения предыдущих перечислителей. Указанные значения могут повторяться.
enum Color { COLOR_RED = -3, COLOR_BLUE, // значение -2 COLOR_GREEN, // значение -1 COLOR_WHITE = 5, COLOR_YELLOW = 5, // значения могут повторяться COLOR_BLACK // значение 6 };
При объявлении перечислимого типа можно задать тип его перечислителей (позволяются только целочисленные типы). В этом случае заданные значения перечислителей будут преобразованы в значения указанного типа.
enum Level : short { LEVEL_LOW = 100, LEVEL_MEDIUM = 0x12345678, // будет значение 0x5678, так как преобразуется к типу short размером 16 бит LEVEL_HIGH };
Значения перечислений неявно преобразуются к целочисленном типу. Однако преобразовать число в перечислимый тип можно только явно. Также явное преобразование потребуется при присвоении значений из других перечислений.
enum Color { COLOR_RED, COLOR_GREEN, COLOR_BLUE }; int color_index = COLOR_RED; Color color1 = 1; // Ошибка Color color2 = static_cast<Color>(1);
Также явное преобразование потребуется при присвоении значений из других перечислений.
enum Color { COLOR_RED, COLOR_GREEN, COLOR_BLUE }; enum Level { LEVEL_LOW, LEVEL_MEDIUM, LEVEL_HIGH }; Color color = COLOR_RED; Level level1 = COLOR_BLUE; // Ошибка Level level2 = static_cast(COLOR_BLUE);
Перечисления с собственной областью видимости
У обычных перечислений есть один недостаток. Например можно сравнить значения из различных перечислений и получить истину. Это происходит из-за того, что при сравнении перечислители преобразуются к целочисленному типу.
Для исправления такого поведения, в стандарте C++11 добавили возможность задавать перечисления с собственной областью видимости. Такие перечисления задаются с помощью конструкции enum class.
enum class Color { RED, GREEN, BLUE };
Поскольку у перечислений теперь есть собственная область видимости, то позволяется использование повторяющихся перечислителей в разных перечислимых типах.
enum class PrimaryColor { RED, GREEN, BLUE }; enum class SecondaryColor { RED, GREEN, BLUE }; // нет ошибки
Обращаться к перечислителям с собственной областью видимости следует через оператор разрешения области видимости :: .
enum class Color { RED, GREEN, BLUE }; Color color = Color::RED;
Для перечислений с областью видимости неявное преобразование к целому числу не работает. Вместо этого следует использовать явное преобразование с помощью static_cast.
enum class Color { RED, GREEN, BLUE }; Color color = Color::RED; int color_index = static_cast<int>(color); // color_index = 0
Также с помощью static_cast можно преобразовать значение одного перечислимого типа к значению другого перечислимого типа.
enum class Color { RED, GREEN, BLUE }; enum class Level { LOW, MEDIUM, HIGH }; Color color = Color::RED; Level level = Level::LOW; if(color == static_cast<Color>(level)) // true { return true; }
Комментарии (0)