>#ifdef
истинна, если переменная была определена, а директива >#ifndef
истинна, если переменная не была определена. В случае истинности проверки выполняется все, что расположено после директивы >#ifdef
или >#ifndef
и до соответствующей директивы >#endif
.Эти средства можно использовать для принятия мер против множественного включения следующим образом:
>#ifndef SALES_DATA_H
>#define SALES_DATA_H
>#include
>struct Sales_data {
> std::string bookNo;
> unsigned units_sold = 0;
> double revenue = 0.0;
>#endif
При первом включении заголовка >Sales_data.h
директива >#ifndef
истинна, и препроцессор обработает строки после нее до директивы >#endif
. В результате переменная препроцессора >SALES_DATA_H
будет определена, а содержимое заголовка >Sales_data.h
скопировано в программу. Если впоследствии включить заголовок >Sales_data.h
в тот же файл, то директива >#ifndef
окажется ложна и строки между ней и директивой >#endif
будут проигнорированы.
Переменные препроцессора, включая имена для защиты заголовка, должны быть уникальными во всей программе. Обычно мы гарантируем уникальность имен защиты заголовка, включая в него имя класса. Чтобы избежать конфликта имен с другими сущностями программы, имена переменных препроцессора обычно пишут полностью в верхнем регистре.
Упражнение 2.42. Напишите собственную версию заголовка >Sales_data.h
и используйте его для новой версии упражнения из раздела 2.6.2.
Резюме
Типы — фундаментальная часть всех программ С++.
Каждый тип определяет требования по хранению и операциям, которые можно выполнять с объектами этого типа. Язык предоставляет набор фундаментальных встроенных типов, таких как >int
и >char
, которые тесно связаны с их представлением на аппаратных средствах машины. Типы могут быть неконстантными или константными; константный объект следует инициализировать. Будучи однажды инициализированным, значение константного объекта не может быть изменено. Кроме того, можно определить составные типы, такие как указатели или ссылки. Составной тип — это тип, определенный в терминах другого типа.
Язык позволяет определять собственные типы, т.е. классы. Библиотека использует классы, чтобы предоставить набор таких высокоуровневых абстракций, как типы IO и >string
.
Термины
Адрес (address). Номер байта в памяти, начиная с которого располагается объект.
Арифметический тип (arithmetic type). Встроенные типы, представляющие логические значения, символы, целые числа и числа с плавающей запятой.
Базовый тип (base type). Спецификатор типа, возможно со спецификатором >const
, который предшествует оператору объявления в объявлении. Базовый тип представляет общий тип, на основании которого строятся операторы объявления в объявлении.