- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания QT 4 программирование GUI на С++ Жасмин Бланшет
Шрифт:
Интервал:
Закладка:
Обычно в пространство имен заключаются все объявления заголовочного файла, чтобы гарантировать невозможность попадания идентификаторов, объявленных в этом заголовочном файле, в глобальное пространство имен. Например:
01 #ifndef SOFTWAREINC_RANDOM_H
02 #define SOFTWAREINC_RANDOM_H
03 namespace SoftwareInc
04 {
05 extern int randomNumbers[128];
06 void populateRandomArray();
07 }
08 #endif
(Обратите внимание на то, что мы переименовали препроцессорные макросимволы, используемые для предотвращения многократного включения содержимого заголовочного файла, снижая риск конфликта имен с заголовочным файлом, имеющим такое же имя, но расположенным в другом каталоге.)
Синтаксис пространства имен совпадает с синтаксисом класса, однако в конце не ставится точка с запятой. Ниже приводится новая версия файла random.cpp:
01 #include "random.h"
02 int SoftwareInc::randomNumbers[128];
03 static int seed = 42;
04 static int nextRandomNumber()
05 {
06 seed = 1009 + (seed * 2011);
07 return seed;
08 }
09 void SoftwareInc::populateRandomArray()
10 {
11 for (int i = 0; i < 128; ++i)
12 randomNumbers[i] = nextRandomNumber();
13 }
В отличие от классов, пространства имен можно «повторно открывать» в любое время. Например:
01 namespace Alpha
02 {
03 void alpha1();
04 void alpha2();
05 }
06 namespace Beta
07 {
08 void beta1();
09 }
10 namespace Alpha
11 {
12 void alpha3();
13 }
Это позволяет определять сотни классов, размещенных во многих заголовочных файлах и принадлежащих одному пространству имен. Используя этот прием, стандартная библиотека С++ помещает все свои идентификаторы в пространство имен std. В Qt пространства имен используются для таких подобных глобальным идентификаторов, как Qt::AlignBottom и Qt::yellow. По историческим причинам классы Qt не принадлежат никакому пространству имен, но имеют префикс 'Q'.
Для ссылки на идентификатор, объявленный в другом пространстве имен, указывается префикс в виде имени этого пространства имен (и ::). Можно поступить по-другому — использовать один из следующих трех механизмов, нацеленных на уменьшение количества вводимых символов:
• Можно определить псевдоним пространства имен:
namespace ElPuebloDeLaReinaDeLosAngeles
{
void beverlyHills();
void culverCity();
void malibu();
void santaMonica();
}
namespace LA = ElPuebloDeLaReinaDeLosAngeles;
После определения псевдонима он может использоваться вместо исходного имени.
• Из пространства имен можно импортировать один идентификатор:
int main()
{
using ElPuebloDeLaReinaDeLosAngeles::beverlyHills;
beverlyHills();
}
Объявление using позволяет обращаться к данному идентификатору без указания префикса, состоящего из имени пространства имен.
• Можно импортировать все пространство имен с помощью одной директивы:
int main()
{
using namespace ElPuebloDeLaReinaDeLosAngeles;
santaMonica();
malibu();
}
При таком подходе конфликты имен становятся более вероятными. Если компилятор «жалуется» на двусмысленное имя (например, когда два класса имеют одинаковое имя, определенное в различных пространствах имен), всегда при ссылке на идентификатор его можно уточнить именем пространства имен.
Препроцессор
Препроцессор С++ — это программа, которая обрабатывает исходный файл .cpp, содержащий директивы # (такие, как #include, #ifndef и #endif), и преобразует его файл исходного кода, который не содержит таких директив. Эти директивы предназначены для выполнения простых операций с текстом исходного файла, например для выполнения условной компиляции, включения файла и разворачивания макроса. Обычно препроцессор автоматически вызывается компилятором, однако в большинстве систем предусмотрена возможность непосредственного его вызова (часто для этого используется опция компилятора —E и /E).
• Директива #include разворачивается в содержимое файла, имя которого указывается в угловых скобках (< >) или в двойных кавычках (" "), в зависимости от расположения заголовочного файла в стандартном каталоге или в каталоге текущего проекта. Имя файла может содержать .. и / (этот символ правильно интерпретируется компиляторами Windows как разделитель каталогов). Например:
#include "../shared/globaldefs.h"
• С помощью директивы #define определяется макрос. Каждое появление в тексте программы имени, расположенном после директивы #define, заменяется определенным для него значением. Например, директива
#define PI 3.14159265359
указывает препроцессору на необходимость замены каждого появления в текущей единице компиляции лексемы PI лексемой 3.14159265359. Для предотвращения конфликтов имен с переменными и классами общей практикой стало назначение макросам имен, состоящих только из прописных букв. Можно определять макрос с аргументами:
#define SQUARE(x) ((x) * (x))
Считается хорошим стилем окружение в теле макроса скобками любых параметров, а также всего тела макроса, что позволяет избегать проблем, связанных с приоритетностью операторов. В конце концов нам нужно, чтобы запись 7 * SQUARE(2 + 3) разворачивалась в 7 * ((2 + 3) * (2 + З)), а не в 7 * 2 + 3 * 2 + 3.
Компиляторы С++ обычно позволяют определять макросы в командной строке, используя опцию —D или /D. Например:
CC -DPI=3.14159265359 -с main.cpp
Макросы были очень популярны в прежние дни, когда еще не были введены typedef, перечисления, константы, встраиваемые функции и шаблоны. В наши дни они играют важную роль в предотвращении многократных включений заголовочных файлов.
• Макрос можно отменить в любом месте с помощью директивы #undef:
#undef PI
Эту возможность необходимо использовать, если требуется переопределить макрос, поскольку препроцессор не позволяет определять один и тот же макрос дважды. Эту директиву полезно также применять для управления условной компиляцией.
• Отдельные фрагменты программного кода можно обрабатывать или пропускать при помощи директив #if, #elif, #else и #endif в зависимости от конкретных числовых значений макросов. Например:
#define NO_OPTIM 0
#define OPTIM_FOR_SPEED 1
#define OPTIM_FOR_MEMORY 2
#define OPTIMIZATION OPTIM_FOR_MEMORY
…
#if OPTIMIZATION == OPTIM_FOR_SPEED
typedef int MyInt;
#elif OPTIMIZATION == OPTIM_FOR_MEMORY
typedef short MyInt;
#else
typedef long long MyInt;
#endif
В приведенном выше примере компилятором будет обрабатываться только второе объявление, которое вводит синоним для short. Изменяя определение макроса OPTIMIZATION, мы получим другие программы. Если макрос не определен, он будет иметь значение 0.
Другим оператором условной компиляции является проверка макроса на предмет его определения. Это можно сделать следующим образом, используя оператор defined():
#define OPTIM_FOR_MEMORY
…
#if defined(OPTIM_FOR_SPEED)
typedef int MyInt;
#elif defined(OPTIM_FOR_MEMORY)
typedef short MyInt;
#else
typedef long long MyInt;
#endif
• Ради удобства препроцессор воспринимает #ifdef X и #ifndef X как синонимы #if defined(X) и #if !defined(X). Для пpeдoтвpaщeния мнoгoкpaтныx включeний заголовочного файла мы окружаем его содержимое следующими директивами:
#ifndef MYHEADERFILE_H
#define MYHEADERFILE_H
…
#endif
При первом включении заголовочного файла символ MYHEADERFILE_H оказывается неопределенным, поэтому компилятор обрабатывает программный код, заключенный между директивами #ifndef и #endif. При повторном и последующих включениях заголовочного файла символ MYHEADERFILE_H оказывается определенным, поэтому весь блок #ifndef … #endif пропускается.
• Директива #errоr генерирует на этапе компиляции определенное пользователем сообщение об ошибке. Эта директива часто используется в комбинации с директивами условной компиляции для вывода сообщения о возникновении недопустимого условия. Например:
class UniChar
{
public:
#if BYTE_ORDER == BIG_ENDIAN
uchar row;