Такие размышления приводят нас к мысли о необходимости функции инициализации, которую нельзя забыть, и об операциях, которые невозможно пропустить. Основным инструментом в этом механизме являются
// простая структура Date,
// гарантирующая инициализацию с помощью конструктора
// и обеспечивающая удобство обозначений
struct Date {
int y, m, d; // год, месяц, день
Date(int y, int m, int d); // проверяем корректность даты
// и выполняем инициализацию
void add_day(int n); // увеличиваем объект типа Date на n дней
};
Функция-член, имя которой совпадает с именем класса, является особой. Она называется
Date my_birthday; // ошибка: объект my_birthday не инициализирован
Date today(12,24,2007); // Ой! Ошибка на этапе выполнения
Date last(2000, 12, 31); // OK (разговорный стиль)
Date christmas = Date(1976,12,24); // также OK (многословный стиль)
Попытка объявить объект my_birthday
today
компилятор пропустит, но проверочный код в конструкторе на этапе выполнения программы обнаружит неправильную дату ((12,24,2007
) — 2007-й день 24-го месяца 12-го года).Определение объекта last
Date
. Этот стиль инициализации переменных класса, имеющего конструктор с аргументами, является наиболее распространенным. Кроме того, можно использовать более многословный стиль, который позволяет явно продемонстрировать создание объекта (в данном случае Date(1976,12,24)
) с последующей инициализацией с помощью синтаксиса инициализации =
. Если вы действительно пишете в таком стиле, то скоро устанете от него.Теперь можно попробовать использовать вновь определенные переменные.
last.add_day(1);
add_day(2); // ошибка: какой объект типа Date?
Обратите внимание на то, что функция-член add_day
Date
с помощью точки, означающей обращение к члену класса. Как определить функцию-член класса, показано в разделе 9.4.4. 9.4.3. Скрываем детали
Остается одна проблема: что произойдет, если мы забудем использовать функцию-член add_day
Date birthday(1960,12,31); // 31 декабря 1960 года
++birthday.d; // Ой! Неправильная дата
Date today(1970,2,3);
today.m = 14; // Ой! Неправильная дата
// today.m == 14
Date
Date
со значением, которое не соответствует календарю. Такие неправильные объекты являются минами с часовым механизмом; через какое-то время кто-нибудь, не ведая того, обязательно воспользуется некорректным значением и получит сообщение об ошибке на этапе выполнения программы или — что еще хуже — получит неверные результаты. Все это лишь вопрос времени.Такие размышления приводят к выводу, что представление типа Date
// простой типа Date (управление доступом)
class Date {
int y, m, d; // год, месяц, день
public:
Date(int y, int m, int d); // проверка и инициализация даты