Шрифт:
int d;
};
Теперь мы должны выбрать дату, заданную по умолчанию. Для этого вполне подходит первый день XXI столетия.
Date::Date
:y(2001), m(Date::jan), d(1)
{
}
const Date& default_date
{
static Date dd(2001,Date::jan,1);
return dd;
}
Здесь использовано ключевое слово
static
, чтобы переменная dd
создавалась только один раз, а не каждый раз при очередном вызове функции default_date
. Инициализация этой переменной происходит при первом вызове функции default_date
. С помощью функции default_date
легко определить конструктор, заданный по умолчанию, для класса Date
.
Date::Date
:y(default_date.year),
m(default_date.month),
d(default_date.day)
}
Обратите внимание на то, что конструктор по умолчанию не обязан проверять значение, заданное по умолчанию; конструктор, создавший объект, вызвавший функцию
default_date
, уже сделал это. Имея конструктор для класса Date
по умолчанию, мы можем создать векторы объектов класса Date
.
vector<Date> birthdays(10);
Без конструктора по умолчанию мы были бы вынуждены сделать это явно.
vector<Date> birthdays(10,default_date);
9.7.4. Константные функции-члены
Некоторые переменные должны изменяться, потому они так и называются, а некоторые — нет; иначе говоря, существуют переменные, которые не изменяются. Обычно их называют константами, и для них используется ключевое слово
const
. Рассмотрим пример.
void some_function(Date& d, const Date& start_of_term)
{
int a = d.day; // OK
int b = start_of_term.day; // должно бы правильно (почему ?)
d.add_day(3); // отлично
start_of_term.add_day(3); // ошибка
}
Здесь подразумевается, что переменная
d
будет изменяться, а переменная start_of_term
— нет; другими словами, функция some_function
не может изменить переменную start_of_term
. Откуда компилятору это известно? Дело в том, что мы сообщили ему об этом, объявив переменную start_of_term
константой (const
). Однако почему же с помощью функции day
можно прочитать переменную day
из объекта start_of_term
? В соответствии с предыдущим определением класса Date
функция start_of_term.day
считается ошибкой, поскольку компилятор не знает, что функция day
не изменяет свой объект класса Date
. Об этом в программе нигде не сказано, поэтому компилятор предполагает, что функция day
может модифицировать свой объект класса Date
, и выдаст сообщение об ошибке.
class Date {
public:
// ...
int day const; // константный член: не может изменять
// объект
Month month const; // константный член: не может изменять
// объект
int year const; // константный член: не может изменять
// объект
void add_day(int n); // неконстантный член: может изменять
// объект
void add_month(int n); // неконстантный член: может изменять
// объект
void add_year(int n); // неконстантный член: может изменять
// объект
private:
int y; // год
Month m;
int d; // день месяца
};
Date d(2000, Date::jan, 20);
const Date cd(2001, Date::feb, 21);
cout << d.day << " — " << cd.day << endl; // OK
d.add_day(1); // OK
cd.add_day(1); // ошибка: cd — константа