0Pricing
C++ Academy · Урок

Перечисление scoped enum class

Типобезопасные перечисления

«Перечисление scoped enum class» — бесплатный урок C++ Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.

Обычные перечисления раскрывают имена

Классическое перечисление в стиле C на основе enum помещает свои имена в окружающую область видимости и неявно преобразуется в int. Из-за этого легко возникают конфликты имён и случайные сравнения.

  • Перечисление с областью видимости устраняет обе проблемы.
  • Значения имеют собственную область видимости и строго типизированы.
#include <iostream>
enum Color { Red, Green, Blue };
int main() {
    Color c = Green;
    int x = c; // implicit conversion to int
    std::cout << x << "\n";
}

Объявление перечисления с областью видимости

Добавьте ключевое слово class (или struct), чтобы создать перечисление с областью видимости. Теперь каждое значение необходимо указывать вместе с именем перечисления.

#include <iostream>
enum class Color { Red, Green, Blue };
int main() {
    Color c = Color::Green;
    if (c == Color::Green) std::cout << "green\n";
}

Нет неявного преобразования

Перечисление с областью видимости не преобразуется неявно в int. Это предотвращает ошибки, когда перечисление случайно используют в арифметике.

  • Чтобы получить число, необходимо выполнить явное приведение типа.
#include <iostream>
enum class Color { Red, Green, Blue };
int main() {
    Color c = Color::Blue;
    int n = static_cast<int>(c); // explicit
    std::cout << n << "\n"; // prints 2
}

Базовый тип

По умолчанию базовым типом является int, но можно выбрать меньший или конкретный целочисленный тип, чтобы сэкономить место или соответствовать протоколу.

#include <iostream>
#include <cstdint>
enum class Status : std::uint8_t { Ok = 0, Warn = 1, Error = 2 };
int main() {
    Status s = Status::Warn;
    std::cout << static_cast<int>(s) << "\n";
}

Пользовательские значения

Элементам перечисления можно назначать явные значения. Значения после явно заданного продолжают отсчёт с него.

#include <iostream>
enum class Http { Ok = 200, NotFound = 404, ServerError = 500 };
int main() {
    Http h = Http::NotFound;
    std::cout << static_cast<int>(h) << "\n";
}

Переключение по перечислению

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

#include <iostream>
enum class Dir { North, East, South, West };
const char* name(Dir d) {
    switch (d) {
        case Dir::North: return "N";
        case Dir::East:  return "E";
        case Dir::South: return "S";
        case Dir::West:  return "W";
    }
    return "?";
}
int main() { std::cout << name(Dir::East) << "\n"; }

Перечисления как аргументы функций

Передача перечисления с областью видимости гораздо лучше выражает намерение, чем передача обычного int или bool. Компилятор гарантирует использование только допустимых значений перечисления.

#include <iostream>
enum class Align { Left, Center, Right };
void render(const char* text, Align a) {
    std::cout << text << " aligned " << static_cast<int>(a) << "\n";
}
int main() { render("Hi", Align::Center); }

Сравнение значений перечисления

Перечисления с областью видимости напрямую поддерживают == и !=. Операторы отношения (<, >) также работают, поскольку значения упорядочены.

#include <iostream>
enum class Level { Low, Medium, High };
int main() {
    Level l = Level::High;
    std::cout << (l > Level::Low ? "above low\n" : "low\n");
}

Концептуальный перебор

Перечисления не перебираются автоматически, но обычно используют приведение через базовые целочисленные значения. Храните специальное значение конца диапазона, например Count, чтобы определять границы.

#include <iostream>
enum class Coin { Penny, Nickel, Dime, Count };
int main() {
    for (int i = 0; i < static_cast<int>(Coin::Count); ++i)
        std::cout << i << " ";
    std::cout << "\n";
}

Почему важна типобезопасность

Два не связанных между собой перечисления с областью видимости нельзя случайно смешать, даже если оба содержат значение с именем None. Компилятор рассматривает их как разные типы.

#include <iostream>
enum class Fruit { None, Apple };
enum class Tool  { None, Hammer };
int main() {
    Fruit f = Fruit::None;
    // Tool t = f; // would NOT compile
    std::cout << (f == Fruit::None) << "\n";
}

Когда использовать обычные перечисления

Обычные перечисления всё ещё встречаются в устаревших программных интерфейсах и коде с битовыми флагами, где удобно неявное преобразование в int. В новом коде предпочитайте перечисления с областью видимости, если нет особой причины поступить иначе.

Быстрая проверка

Проверьте, насколько хорошо Вы поняли перечисления с областью видимости.

Итоги

Вы изучили перечисления с областью видимости:

  • enum class ограничивает область видимости значений и запрещает неявное преобразование в int.
  • Используйте static_cast<int>, чтобы получить число.
  • Выбирайте базовый тип с помощью : type.
  • Предпочитайте enum class для типобезопасного и самодокументируемого кода.

Часто задаваемые вопросы

Урок «Перечисление scoped enum class» бесплатный?

Да — полный текст урока «Перечисление scoped enum class» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.

Чему я научусь в уроке «Перечисление scoped enum class»?

Типобезопасные перечисления Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C++ Academy?

Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Перечисление scoped enum class»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C++ Academy?

Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Перечисление scoped enum class
  2. Объединения и связанные с ними риски
  3. std::variant
  4. std::visit
← Назад к C++ Academy