Как использовать заголовочный файл без файла cpp - PullRequest
1 голос
/ 08 февраля 2012

Я - Java-разработчик, но мне недавно пришлось изучать C ++, и я смущен некоторыми вещами.То, что я хотел бы сделать, это создать «глобальный» заголовочный файл, в котором есть список переменных #define, которые будут постоянными во всем наборе, который я создаю.Я создал файл заголовка и добавил некоторые переменные

#ifndef CONSTANTS_H
#define CONSTANTS_H

#define SM_START            1001;
#define SM_PAUSE            1002;
#define SM_STOP             1003;
#define SM_SAVE             1004;
#define SM_DISCARD          1005;
#define SM_SETUP            1007;


#endif // CONSTANTS_H

Моя проблема в том, что я не могу получить к ним доступ ...

Я включил файл заголовка туда, где он мне нужен,но у меня нет возможности получить доступ к константам внутри него.Должен ли я иметь файл .cpp?есть ли для меня способ доступа к постоянным переменным?

Ответы [ 4 ]

6 голосов
/ 08 февраля 2012

Во-первых: Вы не должны ставить точку с запятой в конце #define. #define - это директива препроцессора, означающая, что она в основном выполняет замену текста определенного имени содержимым. Поэтому, если вы сделаете что-то вроде int a = SM_STOP + 1;, оно будет предварительно обработано до int a = 1003; + 1; с вашим кодом, а это не то, что вам нужно.

Второе: Заголовки обычно не компилируются сами по себе, а только для включения в *.cpp файлы или другие заголовки (где #include снова является текстовой подстановкой). Поэтому, да, вам нужно где-то иметь файл .cpp (ну, не совсем, во-первых, вы можете выбрать другое расширение, а во-вторых, вы можете даже дать компилятору заголовок в качестве модуля компиляции, но я бы посоветовал против, по крайней мере, пока не узнаешь что делаешь). Однако вам не нужно иметь .cpp файл для ваших констант, просто #include ваш заголовок в любой файл, в котором вы хотите использовать константы.

В-третьих: почему вы используете препроцессор здесь? Это похоже на идеальную работу для перечисления. Затем вы можете поместить его в пространство имен / структуру для устранения необходимости префиксировать их (с SM_). Или вы можете просто использовать новый C ++ 11 enum class, который во многом похож на перечисления java. Я бы по возможности избегал препроцессоров. Так как это просто замена текста, и он не учитывает какую-либо область видимости и тому подобное, это облегчает возникновение проблем (например, с вашими точками с запятой).

3 голосов
/ 08 февраля 2012

Проблема в том, что у вас есть точка с запятой после #define.Это единственное, что мешает вам использовать ваши «константы», которые технически не являются константами;это определения препроцессора .

Логически, компилятор C ++ пропускает текст вашей программы через препроцессор, текстовый фильтр, который выполняет директивы, начинающиеся с #.Директива #define предписывает препроцессору найти все вхождения его левой части и дословно заменить их правой частью.В вашем случае он включает точки с запятой, что приводит к неверным выражениям после замены.

Например,

if (command == SM_DISCARD) ...

становится

if (command == 1005;) ...

Это ошибка, икомпилятор сообщает, что это неверный синтаксис.

2 голосов
/ 08 февраля 2012

Используйте #include <constants.h> или любое другое имя вашего файла, чтобы включить этот файл. Кроме того, вам не нужны точки с запятой. #defines - это текстовые замены, выполняемые в коде компилятором.

0 голосов
/ 08 февраля 2012

Вам не нужен файл cpp. Включая заголовок достаточно.

Препроцессор расширяет ваши определения тем, что следует за ним.

SM_START станет 1001;

Так что выражение вроде:

int x = SM_START;

будет переводиться на

int x = 1001;;

что все еще законно.

Но эта точка с запятой может привести к неприятностям во что-то вроде:

int x = SM_START * 10;

, который будет расширен до:

int x = 1001; * 10;

что явно незаконно.

Кроме того, директивы препроцессора не следует путать с глобальными. Даже если вы, вероятно, не должны использовать глобальные переменные, использование #defines, вероятно, хуже, чем определение class Global или просто использование переменных, сгруппированных в namespace.

...