Д. Стефенс - C++. Сборник рецептов
- Название:C++. Сборник рецептов
- Автор:
- Жанр:
- Издательство:КУДИЦ-ПРЕСС
- Год:2007
- Город:Москва
- ISBN:5-91136-030-6
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Д. Стефенс - C++. Сборник рецептов краткое содержание
Данная книга написана экспертами по C++ и содержит готовые рецепты решения каждодневных задач для программистов на С++. Один из авторов является создателем библиотеки Boost Iostreams и нескольких других библиотек C++ с открытым исходным кодом. В книге затрагивается множество тем, вот лишь некоторые из них: работа с датой и временем; потоковый ввод/вывод; обработка исключений; работа с классами и объектами; сборка приложений; синтаксический анализ XML-документов; программирование математических задач. Читатель сможет использовать готовые решения, а сэкономленное время и усилия направить на решение конкретных задач.
C++. Сборник рецептов - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
// Здесь поместите все. что требуется...
#endif // MYCLASS_H__
Когда препроцессор сканирует такой заголовочный файл, одной из первых встреченных им вещей будет директива #ifndef
и следующий за ней символ, #ifndef
говорит препроцессору перейти на следующую строку только в том случае, если символ MYCLASS_H__
еще не определен. Если он уже определен, препроцессор должен пропустить код до закрывающей директивы #endif
. Строка, следующая за #ifndef
, определяет MYCLASS_H__
, так что если этот файл при одной и той же компиляции сканируется препроцессором дважды, то второй раз MYCLASS_H__
будет уже определен. Поместив весь код между #ifndef
и #endif
, вы гарантируете, что в процессе компиляции он будет прочитан только один раз.
Если вы не используете эту методику, которая называется защитой заголовка , то вы, вероятно, уже видели ошибки компиляции «symbol already defined» (символ уже определен), которые являются следствием отсутствия защитных мер против множественных определений. C++ не позволяет определять один и тот же символ несколько раз, и если вы это сделаете (целенаправленно или случайно), то получите ошибку компилятора. Включение защиты предотвращает такие ошибки, и она стала стандартной методикой.
Определяемый с помощью #define
макрос не обязан следовать какому-либо формату, но использованный мной синтаксис имеет широкое распространение. Его идея состоит в том, чтобы использовать символ, который не будет конфликтовать с другим макросом, в результате чего файл будет непреднамеренно пропускаться препроцессором. На практике вы можете столкнуться и с другими методиками, такими как включение в макрос версии заголовочного файла или модуля, т.е. MYCLASS_H_V301__
, или, возможно, имени автора. Не имеет значения, как вы его назвали, до тех пор, пока вы придерживаетесь единой схемы. Эти макросы должны использоваться только в заголовочном файле, который они защищают, и больше нигде.
В некоторых фрагментах кода можно увидеть внешнюю защиту заголовков , которая аналогична описанной ранее внутренней защите заголовков , за исключением того, что она используется в файле, включающем заголовочный файл, а не в самом заголовочном файле.
#ifndef MYCLASS_H__
#include "myclass.h"
#endif
Это сокращает процесс включения, поскольку, если макрос MYCLASS_H__
уже определен, файл myclass.h
даже не подключается. Несколько лет назад утверждалось, что внешняя защита заголовков в больших проектах снижает время компиляции, но компиляторы совершенствуются и внешняя защита больше не требуется. Не используйте ее.
Даже если вы работаете над небольшим проектом, всегда следует помещать в заголовочный файл защиту заголовка. Если заголовочный файл включается в более чем одном файле, имеется вероятность, что в один прекрасный момент вы увидите ошибку переопределения. Более того, небольшие проекты стремятся за очень короткое время превратиться в большие, и хотя проект мог начинаться с единственного исполняемого файла и набора заголовочных файлов, включаемых только один раз, рано или поздно проект вырастет, и начнут появляться ошибки компиляции. Если вы с самого начала добавите защиту заголовков, вам не придется в будущем возвращаться и добавлять их сразу в большое количество файлов.
2.2. Обеспечение единственности экземпляра переменной при большом количестве исходных файлов
Требуется, чтобы одна и та же переменная использовалась различными модулями программы, а копия переменной должна быть только одна. Другими словами, это должна быть глобальная переменная .
Объявите и определите как обычно переменную в одном файле реализации, а в других файлах реализации, где требуется доступ к этой переменной, используйте ключевое слово extern
. Часто это означает включение объявлений extern
в заголовочные файлы, используемые файлами реализаций, которым требуется доступ к глобальной переменной. Пример 2.3 содержит несколько файлов, которые показывают, как используется ключевое слово extern
для доступа к переменным, определенным в другом файле реализации.
Пример 2.3. Использование ключевого слова extern
// global.h
#ifndef GLOBAL_H__ // см. рецепт 2.0
#define GLOBAL_H__
#include
extern int x;
extern std::string s;
#endif
// global.cpp
#include
int x = 7;
std::string s = "Kangaroo";
// main.cpp
#include
#include "global.h"
using namespace std;
int main() {
cout << "x = " << x << endl;
cout << "s = " << s << endl;
}
Ключевое слово extern
— это способ сказать компилятору, что реальная область памяти для переменной выделяется в другом месте, extern
говорит компоновщику, что переменная описана где-то в другом объектном файле и что компоновщик должен найти ее при создании конечного исполняемого файла или библиотеки. Если компоновщик не находит переменной, объявленной как extern
, или если он находит более одного ее определения, он генерирует ошибку компоновки.
Пример 2.3 не слишком впечатляет, но он хорошо иллюстрирует вопрос. Две мои глобальные переменные объявляются в global.cpp :
int x = 7;
std::string s = "Kangaroo";
Мне требуется доступ к ним из других файлов реализации, так что я поместил в заголовочный файл global.h объявление extern
для них:
extern int x;
extern std::string s
;
Разница между объявлением и определением очень важна. В C++ можно объявить что-либо несколько раз, при условии совпадения объявлений, но определить что-либо можно только один раз. Это называется правилом одного определения (на самом деле в некоторых случаях определить объект можно несколько раз, но только если определения абсолютно идентичны — обычно это бессмысленно). Ключевое слово extern
— это механизм, позволяющий сказать компилятору и компоновщику, что определение находится где-то еще и что оно должно быть разрешено при компоновке.
Нельзя сказать, что использование extern
должно быть постоянным. Его следует использовать обдуманно и только тогда, когда это необходимо, так как оно позволяет создавать переменные, глобальные для всего приложения. Иногда оно может потребоваться для поистине глобальных объектов или данных — объекта журналирования, оборудования, большого объекта общих данных, но в большинстве случаев имеются более адекватные альтернативы.
2.3. Снижение числа #include с помощью предварительного объявления классов
Имеется заголовочный файл, который ссылается на классы из других заголовочных файлов, и требуется снизить зависимости компиляции (и, возможно, время).
Читать дальшеИнтервал:
Закладка: