Перечисление 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 — локальная установка не требуется.
Все уроки этого курса
- Перечисление scoped enum class
- Объединения и связанные с ними риски
- std::variant
- std::visit