×
Traktatov.net » Язык программирования C++. Пятое издание » Читать онлайн
Страница 64 из 714 Настройки
и >totalRevenue соответственно. Выводим эти значения, а затем проверяем, были ли книги проданы, и если да, то выводим вычисленную среднюю цену за книгу. Если никаких продаж не было, выводим сообщение, обращающее внимание на этот факт.

Упражнения раздела 2.6.2

Упражнение 2.41. Используйте класс >Sales_data для перезаписи кода упражнений из разделов 1.5.1, 1.5.2 и 1.6. А также определите свой класс >Sales_data в том же файле, что и функция >main().

2.6.3. Создание собственных файлов заголовка

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

Чтобы гарантировать совпадение определений класса в каждом файле, классы обычно определяют в файлах заголовка. Как правило, классы хранятся в заголовках, имя которых совпадает с именем класса. Например, библиотечный тип >string определен в заголовке >string. Точно так же, как уже было продемонстрировано, наш класс >Sales_data определен в файле заголовка >Sales_data.h.

Заголовки (обычно) содержат сущности (такие как определения класса или переменных >const и >constexpr (см. раздел 2.4), которые могут быть определены в любом файле только однажды. Однако заголовки нередко должны использовать средства из других заголовков. Например, поскольку у класса >Sales_data есть член типа >string, заголовок >Sales_data.h должен включать заголовок >string. Как уже упоминалось, программы, использующие класс >Sales_data, должны также включать заголовок >string, чтобы использовать член >bookNo. В результате использующие класс >Sales_data программы будут включать заголовок >string дважды: один раз непосредственно и один раз как следствие включения заголовка >Sales_data.h. Поскольку заголовок мог бы быть включен несколько раз, код необходимо писать так, чтобы обезопасить от многократного включения.

После внесения любых изменений в заголовок необходимо перекомпилировать все использующие его файлы исходного кода, чтобы вступили в силу новые или измененные объявления.

Краткое введение в препроцессор

Наиболее распространенный способ обезопасить заголовок от многократного включения подразумевает использование препроцессора. Препроцессор (preprocessor), унаследованный языком С++ от языка С, является программой, которая запускается перед компилятором и изменяет исходный текст программ. Наши программы уже полагаются на такое средство препроцессора, как директива >#include. Когда препроцессор встречает директиву >#include, он заменяет ее содержимым указанного заголовка.

Программы С++ используют также препроцессор для защиты заголовка (header guard). Защита заголовка полагается на переменные препроцессора (см. раздел 2.3.2). Переменные препроцессора способны находиться в одном из двух состояний: она либо определена, либо не определена. Директива