Перечисления, структуры и объединения
Три способа создать собственные типы данных
int, double, bool) редко хватает для описания реальной задачи. C++ позволяет проектировать свои типы. Перечисление (enum) называет фиксированный набор связанных значений, структура (struct) объединяет несколько полей в один набор, а объединение (union) позволяет нескольким полям делить одну и ту же память. Умение выбрать нужное - ключевой навык среднего уровня.
- объявлять область-ограниченное
enum classи управлять его базовым типом, - определять
structс полями, инициализаторами по умолчанию и функциями-членами, - понимать, что такое
unionи почему он опасен без тега, - выбирать правильный инструмент - и знать, когда
std::variantзаменяет сырое объединение.
1. Перечисления: имя для каждого допустимого значения
Представьте светофор. Он никогда не бывает "7" или "-3" - только Красный, Жёлтый или Зелёный. Перечисление (enum) - это тип, значения которого вы перечисляете по имени, поэтому компилятор гарантирует использование только этих имён.
Современный C++ предпочитает область-ограниченное перечисление, записываемое как enum class. Его имена живут внутри области самого перечисления и оно не преобразуется молча в int.
enum class Color { Red, Yellow, Green };
Color c = Color::Green; // нужно уточнять через Color::
// int n = c; // ОШИБКА: нет неявного преобразования
int n = static_cast<int>(c); // OK: явно, n == 2
По умолчанию первое имя равно 0, следующее 1 и так далее. Вы можете задать значения сами и выбрать базовый тип (целочисленный тип для хранения):
enum class Status : unsigned char {
Ok = 0,
Warning = 10,
Error = 20
};
Старый стиль, обычное enum Color { Red, Green };, выбрасывает Red и Green прямо в окружающую область и сам преобразуется в int. Эта вольность вызывает конфликты имён и скрытые ошибки - именно поэтому в C++11 добавили enum class.
enum class. Обычный enum берите только для старомодных битовых флагов, где автоматическое преобразование в int действительно удобно.