Программирование. Принципы и практика использования C++ Исправленное издание, стр. 129
Date::Date(int yy, int mm, int dd) :y(yy), m(mm), d(dd) // инициализация данных - членов класса { if (!check()) throw Invalid(); // проверка корректности}bool Date::check() // возвращает true, если дата корректна{ if (m<1 || 12<m) return false; // ...}Имея это определение класса
Datevoid f(int x, int y)try { Date dxy(2009,x,y); cout << dxy << '\n'; // объявление оператора << см. в разделе 9.8 dxy.add_day(2);}catch(Date::Invalid) { error("invalid date"); // функция error() определена // в разделе 5.6.3}Теперь мы знаем, что оператор
<<add_day()DateDate9.5. Перечисления
enumenum Month { jan=1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec};“Тело” перечисления — это просто список его элементов. Каждому элементу перечисления можно задать конкретное значение, как это сделано выше с элементом
janMonthenum Month { jan=1, feb=2, mar=3, apr=4, may=5, jun=6, jul=7, aug=8, sep=9, oct=10, nov=11, dec=12};Однако это утомительно и открывает много возможностей для ошибок. Фактически мы сделали две опечатки, пока не получили правильный вариант; лучше все же предоставить компилятору делать простую, повторяющуюся, “механическую” работу. Компилятор такие задачи решает лучше, чем люди, и при этом не устает.
Если не инициализировать первый элемент перечисления, то счетчик начнет отсчет с нуля. Рассмотрим такой пример:
enum Day { monday, tuesday, wednesday, thursday, friday, saturday, sunday};где
monday==0sunday==6Перечисление
MonthMonth m = feb;m = 7; // ошибка: нельзя присвоить целое число перечислениюint n = m; // OK: целочисленной переменной можно присвоить // значение MonthMonth mm = Month(7); // преобразование типа int в тип Month //(без проверки)
MonthintMonthintMonthMonthMonth bad = 9999; // ошибка: целое число невозможно преобразовать // объект типа Month
Month(9999)К сожалению, мы не можем определить конструктор для перечисления, чтобы проверить начальные значения, но написать простую функцию для проверки не составляет труда.
Month int_to_month(int x){ if (x<jan || dec<x) error("неправильный месяц"); return Month(x);}Теперь можно написать следующий код:
void f(int m){ Month mm = int_to_month(m); // ...}Для чего нужны перечисления? В основном перечисление полезно, когда нам нужно множество связанных друг с другом именованных целочисленных констант. Как правило, с помощью перечислений представляют наборы альтернатив (
updownyesnomaybeonoffnneesesswwnwredbluegreenyellowmarooncrimsonblack