Перечисления

Последнее обновление: 16.02.2023

Перечисления (enum) представляют еще один способ определения своих типов. Их отличительной особенностью является то, что они содержат набор числовых констант. Перечисление имеет следующую форму:

enum class имя_перечисления { константа_1, константа_2, ... константа_N};

После ключевых enum class идет название перечисления, и затем в фигруных скобках перечисляются через запятую константы перечисления.

Определим простейшее перечисление:

enum class Day {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday}

В данном случае перечисление называется Day и представляет дни недели. В фигурных скобках заключены все дни недели. Фактически они представляют числовые константы.

Каждой константе сопоставляется некоторое числовое значение. По умолчанию первая константа получает в качестве значения 0, а остальные увеличиваются на единицу. Так, в примере выше Monday будет иметь значение 0, Tuesday - 1 и так далее. Таким образом, последняя константа - Sunday будет равна 6.

После создания перечисления мы можем определить его переменную и присвоить ей одну из констант:

Day today {Day::Thursday};
// или так
//Day today = Day::Thursday;

В данном случае определяется переменная today, которая равна Day::Thursday, то есть четвертой константе перечисления Day.

Чтобы вывести значение переменной на консоль, можно использовать преобразование к типу целочисленному типу:

#include <iostream>

enum class Day {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};
int main()
{
    Day today {Day::Thursday};
    std::cout << "Today: " << static_cast<int>(today) << std::endl;
}

То есть в данном случае на консоль будет выведено Today: 3, так как константа Thursday имеет значение 3.

Мы также можем управлять установкой значений в перечислении. Так, мы можем задать начальное значение для одной контанты, тогда у последуюших констант значение увеличивается на единицу:

enum class Day {Monday = 1, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};

В данном случае Tuesday будет равно 2, а Sunday - 7.

Можно назначить каждой константе индивидуальное значение или сочетать этот подход с автоустановкой:

enum class Day {Monday = 2, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday=1};

В данном случае Saturday будет равно 7, а Sunday - 1.

Можно даже назначать двум константам одно и то же значение:

enum class Day {Monday = 1, Mon = 1, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday };

Здесь константы Monday и Mon имеют одно и то же значение.

Можно присвоить константам значение уже имеющихся констант:

enum class Day {Monday = 1, Mon = Monday, Tuesday = Monday + 1, Wednesday, Thursday, Friday, Saturday, Sunday };

Стоит учитывать, что константы перечисления должны представлять целочисленные константы. Однако мы можем выбрать другой целочисленный тип, например, char:

enum class Operation: char {Add = '+', Subtract='-', Multiply='*'};

Если мы захотим вывести значения этих констант на консоль в виде символов, то необходимо преобразовать их к типу char:

#include <iostream>

enum class Operation: char {Add = '+', Subtract='-', Multiply='*'};
int main()
{
    std::cout << "add: " << static_cast<char>(Operation::Add) << std::endl;
    std::cout << "subtracte: " << static_cast<char>(Operation::Subtract) << std::endl;
    std::cout << "multiply: " << static_cast<char>(Operation::Multiply) << std::endl;
}

Применение перечислений

Перечисления удобны, когда необходимо хранить ограниченный набор состояний и в зависимости от текущего состояния выполнять некоторые действия. Например:

#include <iostream>

enum class Operation {Add, Subtract, Multiply};

void calculate(int n1, int n2, Operation op)
{
    switch (op)
    {
        case Operation::Add: 
            std::cout << n1 + n2 << std::endl;
            break;
        case Operation::Subtract:
            std::cout << n1 - n2 << std::endl;
            break;
        case Operation::Multiply:
            std::cout << n1 * n2 << std::endl;
            break;
    }
}
int main()
{
    calculate(10, 6, Operation::Add);           // 16
    calculate(10, 6, Operation::Subtract);      // 4
    calculate(10, 6, Operation::Multiply);      // 60
}

В данном случае все арифметические операции хранятся в перечислении Operation. В функции calculate зависимости от значения третьего параметра - применяемой операции выполняются определенные действия с двумя первыми параметрами.

Подключение констант перечисления

При обращении к контантам перечисления по умолчанию необходимо указывать название перечисления, например, Day::Monday. Но начиная со стандарта C++20 мы можем подключить константы перечисления в текущий контекст с помощью оператора using.

using enum Day;

И в дальнейшем использовать только имя констант:

#include <iostream>

enum class Day {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};
using enum Day;     // подключаем константы перечисления в текущую область видимости

int main()
{
    Day today {Thursday};	// используем только имя константы
    // или так 
    //Day today = Thursday;
    std::cout << static_cast<int>(today) << std::endl;      // 3
    // выводим значение констаты Sunday
    std::cout << static_cast<int>(Sunday) << std::endl;     // 6
}

Также мы можем подключить только одну константу:

using Day::Monday;     // подключаем только Monday
........................
Day today {Monday};

В данном случае подключаем только константу Day::Monday. Для обращения к дргуим константам по прежднему необходимо использовать имя перечисления.

Поскольку такая возможность добавлена лишь начиная со стандарта С++20, то при компиляции с g++ или clang++ добавляется соответствующий флаг - -std=c++20

Перечисления в С-стиле

Стоит отметить, что раньше в С++ использовалась другая форма перечислений, которые пришли из языка С и определяются без ключевого слова class:

#include <iostream>

enum Day {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};

int main()
{
    Day today = Tuesday;
    std::cout << today << std::endl;    // 1 
}

Такие перечисления еще называют unscoped (то есть не ограниченные ни какой областью видимостью). Естественно такие перечисления можно встретить в старых программах. Однако в виду того, что они потенциально могут привести к большему количеству ошибок, то в настоящее время такая форма все меньше и меньше используется.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850