Здесь использовано ключевое слово 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
Без конструктора по умолчанию мы были бы вынуждены сделать это явно.
vector
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 — константа
Ключевое слово const
int Date::day const
{
++d; // ошибка: попытка изменить объект в константной
// функции - члене
return d;
}
Естественно, как правило, мы не собираемся мошенничать. В основном компилятор обеспечивает защиту от несчастных случаев, что очень полезно при разработке сложных программ.
9.7.5. Члены и вспомогательные функции