Чтение онлайн

на главную

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

Date sunday(2009,8,29); // инициализируем объект Sunday

// триадой (2009,8,29)

Функцию-член класса можно также определить в определении класса.

// простой класс Date (детали реализации будут рассмотрены позднее)

class Date {

public:

Date(int yy, int mm, int dd)

:y(yy), m(mm), d(dd)

{

// ...

}

void add_day(int n)

{

// ...

}

int month { return m; }

// ...

private:

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

};

Во-первых, отметим, что теперь объявление класса стало больше и запутаннее. В данном примере код конструктора и функции

add_day
могут содержать десятки строк. Это в несколько раз увеличивает размер объявления класса и затрудняет поиск интерфейса среди деталей реализации. Итак, мы не рекомендуем определять большие функции в объявлении класса. Тем не менее посмотрите на определение функции
month
. Оно проще и короче, чем определение
Date::month
, размещенное за пределами объявления класса. Определения коротких и простых функций можно размещать в объявлении класса.

Обратите внимание на то, что функция

month
может обращаться к переменной m, даже несмотря на то, что переменная m определена позже (ниже) функции
month
. Член класса может ссылаться на другой член класса независимо от того, в каком месте класса он определен. Правило, утверждающее, что имя переменной должно быть объявлено до ее использования, внутри класса ослабляется.

Определение функции-члена в классе приводит к следующим последствиям.

• Функция становится подставляемой (inlined), т.е. компилятор попытается сгенерировать код подставляемой функции вместо ее вызова. Это может дать значительное преимущество часто вызываемым функциям, таким как

month
.

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

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

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) // инициализация данных - членов класса

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

Черный Маг Императора 13

Герда Александр
13. Черный маг императора
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Черный Маг Императора 13

Последняя Арена 4

Греков Сергей
4. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 4

Маяк надежды

Кас Маркус
5. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Маяк надежды

Великий перелом

Ланцов Михаил Алексеевич
2. Фрунзе
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Великий перелом

Сопротивляйся мне

Вечная Ольга
3. Порочная власть
Любовные романы:
современные любовные романы
эро литература
6.00
рейтинг книги
Сопротивляйся мне

Инквизитор Тьмы 2

Шмаков Алексей Семенович
2. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы 2

Мастер Разума V

Кронос Александр
5. Мастер Разума
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Мастер Разума V

Бандит 2

Щепетнов Евгений Владимирович
2. Петр Синельников
Фантастика:
боевая фантастика
5.73
рейтинг книги
Бандит 2

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Падение Твердыни

Распопов Дмитрий Викторович
6. Венецианский купец
Фантастика:
попаданцы
альтернативная история
5.33
рейтинг книги
Падение Твердыни

"Дальние горизонты. Дух". Компиляция. Книги 1-25

Усманов Хайдарали
Собрание сочинений
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Дальние горизонты. Дух. Компиляция. Книги 1-25

Ох уж этот Мин Джин Хо 2

Кронос Александр
2. Мин Джин Хо
Фантастика:
попаданцы
5.00
рейтинг книги
Ох уж этот Мин Джин Хо 2

Энфис 6

Кронос Александр
6. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Энфис 6