Программирование. Принципы и практика использования C++ Исправленное издание, стр. 127
class Date { int y, m, d; // год, месяц, деньpublic: Date(int y, int m, int d); // проверка и инициализация даты void add_day(int n); // увеличение объекта типа Date на n дней int month() { return m; } int day() { return d; } int year() { return y; }};Этот класс можно использовать следующим образом:
Date birthday(1970, 12, 30); // OKbirthday.m = 14; // ошибка: Date::m — закрытый членcout << birthday.month() << endl; // доступ к переменной m
DateВ качестве альтернативы можно проверять корректность объекта при каждой попытке его использования или просто надеяться на то, что никто никогда не создаст ни одного некорректного значения. Опыт показывает, что такие надежды могут привести к “очень хорошим” программам. Однако создание таких программ, которые иногда выдают ошибочные результаты, а порой вообще приводят к аварийному отказу, не принесет вам профессионального признания. Мы предпочитаем писать программы, корректность которых можно продемонстрировать.
DateDateDatestruct9.4.4. Определение функций-членов
До сих пор мы смотрели на класс
DateDate// простой класс Date (детали реализации будут рассмотрены позднее)class Date {public: Date(int y, int m, int d); // проверка и инициализация даты void add_day(int n); // увеличивает объект класса Date на n дней int month(); // ...private: int y, m, d; // лет, месяцев, дней};Открытый интерфейс разрабатывают в первую очередь, поскольку именно он интересует большинство людей. В принципе пользователю не обязательно знать детали реализации. На самом же деле люди, как правило, любопытны и хотят знать, насколько разумна реализация класса и какие приемы использовал ее автор, чтобы научиться у него чему-нибудь. И все же, если реализацию класса создавали не мы, то большую часть времени будем работать с его открытым интерфейсом. Компилятору безразличен порядок следования членов класса; он обрабатывает объявления в любом порядке, в котором мы их укажем.
Определяя члены за пределами класса, мы должны указать, какому классу они принадлежат. Для этого используется обозначение имя_класса::имя_члена.
Date::Date(int yy, int mm, int dd)// конструктор :y(yy), m(mm), d(dd) // примечание: инициализация члена{}void Date::add_day(int n){ // ...}int month() // Ой: мы забыли про класс Date::{ return m; // не функция-член, к переменной m доступа нет}Обозначение
:y(yy)m(mm)d(dd)Date::Date(int yy, int mm, int dd) // конструктор{ y = yy; m = mm; d = dd;}Однако сначала нам следовало бы инициализировать члены их значениями, заданными по умолчанию, и лишь потом присваивать им новые значения. Кроме того, в этом случае не исключена возможность того, что мы случайно используем член класса до его инициализации. Обозначение
:y(yy)m(mm)d(dd)int x; // сначала определяем переменную x// ...x = 2; // потом присваиваем ей значениеВторой пример выглядит так:
int x = 2; // определяем и немедленно инициализируем двойкой