• Ради удобства препроцессор воспринимает #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;
uchar cell;
#elif BYTE_ORDER == LITTLE_ENDIAN
uchar cell;
uchar row;
#else
#error "BYTE_ORDER must be BIG_ENDIAN or LITTLE_ENDIAN"
#endif
};
В отличие от большинства других конструкций С++, в которых недопустимы пробельные символы, препроцессорные директивы должны быть единственными в строке и не должны содержать точку с запятой. Слишком длинные директивы можно разбивать на несколько строк, заканчивая каждую строку, кроме последней, обратной наклонной чертой.
Стандартная библиотека С++
В данном разделе мы кратко рассмотрим стандартную библиотеку С++. На рис. Б.З приводится список базовых заголовочных файлов С++:
• — шаблонный класс для представления последовательностей битов фиксированной длины,
• — шаблонный класс для представления комплексных чисел,
• — типы и функции, относящиеся к обработке исключений,
• — шаблонный класс, определяющий свойства числовых типов,
• — классы и функции, относящиеся к локализации,
• — функции, управляющие динамическим распределением памяти,
• — заранее определенные типы исключений для вывода сообщений об ошибках,
• — шаблонный строковый контейнер и свойства символов,
• — класс, предоставляющий основную метаинформацию о типах,
• — шаблонные классы для представления массивов значений.
Заголовочные файлы , , и поддерживают возможности языка С++; например, позволяет проверять возможности поддержки компилятором целочисленной арифметики и арифметики чисел с плавающей точкой, a предлагает основные средства анализа информации о типах. Другие заголовочные файлы предоставляют часто используемые классы, в том числе класс строки и тип комплексных чисел. Функциональность, предлагаемая заголовочными файлами , , и , свободно перекрывается в Qt классами QBitArray, QLocale, QString и QMetaObject.
Стандартный С++ также включает ряд заголовочных файлов, обеспечивающих ввод—вывод (см. рис. Б.4):
• — шаблонные классы, манипулирующие внешними файлами,
• — манипуляторы потоков ввода—вывода, принимающие один аргумент,
• — шаблонный базовый класс потоков ввода—вывода,
• — предварительные объявления нескольких шаблонных классов потоков ввода—вывода,
• — стандартные потоки ввода—вывода (cin, cout, cerr, ctog),
• — шаблонный класс, управляющий вводом из буфера потока,
• — шаблонный класс, управляющий выводом в буфер потока,
• — шаблонные классы, связывающие буферы потоков со строками,
• — шаблонные классы, обеспечивающие буфер для операций ввода—вывода,
• — классы для выполнения операций потокового ввода-вывода с массивами символов.
Классы стандартного ввода—вывода проектировались в 80-х годах и обладают излишней сложностью, что сильно затрудняет их понимание, причем настолько, что этой теме были посвящены целые книги. Кроме того, программист остается наедине с ящиком Пандоры неразрешенных проблем, связанных с кодировкой символов и зависимого от платформы двоичного представления элементарных типов данных.
В главе 12 («Ввод—вывод») представлены соответствующие классы Qt, обеспечивающие ввод—вывод символов в кодировке Unicode, а также большой набор национальных кодировок и абстракцию независимого от платформы хранения двоичных данных. Qt—классы ввода—вывода формируют основу поддержки межпроцессной связи, работы с сетями и XML. Qt—классы двоичных и текстовых потоков можно очень легко расширить для работы с пользовательскими типами данных.
В начале 90-х годов была введена стандартная библиотека шаблонов (Standard Template Library — STL), представляющая собой набор шаблонных классов-контейнеров, итераторов и алгоритмов, которые вошли в стандарт ISO С++ в последний момент. На рис. Б.5 приводится список заголовочных файлов библиотеки STL:
• — шаблонные функции общего назначения,