Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

int d;

};

Теперь мы должны выбрать дату, заданную по умолчанию. Для этого вполне подходит первый день XXI столетия.

Date::Date

:y(2001), m(Date::jan), d(1)

{

}

Если не хотите встраивать значение, заданное по умолчанию, в код конструктора, то можете использовать константу (или переменную). Для того чтобы избежать использования глобальных переменных и связанных с ними проблем инициализации, можно использовать прием, описанный в разделе 8.6.2.

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 — константа

  • Читать дальше
  • 1
  • ...
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: