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

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

Шрифт:

Очевидное правило гласит: не помещайте тела функций-членов в объявление класса, если вам не нужна повышенная эффективность программы за счет использования небольших подставляемых функций. Большие функции, скажем, состоящие из пяти и более строк, ничего не выиграют от подстановки. Не следует делать подставляемыми функции, содержащие более одного-двух выражений.

9.4.5. Ссылка на текущий объект

Рассмотрим простой пример использования класса

Date
.

class Date {

// ...

int month { return m; }

// ...

private:

int y, m, d; // год, месяц, день

};

void f(Date d1, Date d2)

{

cout << d1.month << ' ' << d2.month << '\n';

}

Откуда функции

Date::month
известно, что при первом вызове следует вернуть значение переменной
d1.m
, а при втором —
d2.m
? Посмотрите на функцию
Date::month
еще раз; ее объявление не имеет аргумента! Как функция
Date::month
“узнает”, для какого объекта она вызывается? Функции-члены класса, такие как
Date::month
, имеют неявный аргумент, позволяющий идентифицировать объект, для которого они вызываются. Итак, при первом вызове переменная m правильно ссылается на
d1.m
, а при втором — на
d2.m
. Другие варианты использования неявного аргумента описаны в разделе 17.10.

9.4.6. Сообщения об ошибках

Что делать при обнаружении некорректной даты? В каком месте кода происходит поиск некорректных дат? В разделе 5.6 мы узнали, что в этом случае следует сгенерировать исключение, и самым очевидным местом для этого является место первого создания объекта класса
Date
. Если мы создали правильные объекты класса
Date
и все функции-члены написаны правильно, то мы никогда не получим объект класса
Date
с неверным значением. Итак, следует предотвратить создание неправильных объектов класса
Date
.

// простой класс Date (предотвращаем неверные даты)

class Date {

public:

class Invalid { }; // используется как исключение

Date(int y, int m, int d); // проверка и инициализация даты

// ...

private:

int y, m, d; // год, месяц, день

bool check; // если дата правильная, возвращает true

};

Мы поместили проверку корректности даты в отдельную функцию

check
, потому что с логической точки зрения эта проверка отличается от инициализации, а также потому, что нам может потребоваться несколько конструкторов. Легко видеть, что закрытыми могут быть не только данные, но и функции.

Date::Date(int yy, int mm, int dd)

:y(yy), m(mm), d(dd) // инициализация данных - членов класса

{

if (!check) throw Invalid; // проверка корректности

}

bool Date::check // возвращает true, если дата корректна

{

if (m<1 || 12<m) return false;

// ...

}

Имея это определение класса

Date
, можно написать следующий код:

void f(int x, int y)

try {

Date dxy(2009,x,y);

cout << dxy << '\n'; // объявление оператора << см. в разделе 9.8

dxy.add_day(2);

}

catch(Date::Invalid) {

error("invalid date"); // функция error определена

// в разделе 5.6.3

}

Теперь мы знаем, что оператор

<<
и функция
add_day
всегда будут работать с корректными объектами класса
Date
. До завершения разработки класса
Date
, описанной в разделе 9.7, опишем некоторые свойства языка, которые потребуются нам для того, чтобы сделать это хорошо: перечисления и перегрузку операторов.

  • Читать дальше
  • 1
  • ...
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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