如何使用没有cpp文件的头文件

时间:2012-02-08 14:55:35

标签: c++ header global-variables constants

我是一名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 个答案:

答案 0 :(得分:6)

首先:你不应该把分号放在#define的末尾。 #define是一个预处理程序指令,这意味着它基本上用内容替换已定义名称的文本。因此,如果您执行int a = SM_STOP + 1;之类的操作,则会使用您的代码对int a = 1003; + 1;进行预处理,这不是您想要的。

第二:标题通常不是自己编译的,而是仅包含在*.cpp文件或其他标题中(其中#include再次是文本替换)。因此,是的,你需要在某个地方有一个.cpp文件(确切地说,首先你可以选择一个不同的扩展名,然后你甚至可以给编译器一个标题作为编译单元,但我会反对它,至少在你知道自己在做什么之前。但是,您不需要为常量提供.cpp文件,只需将#include标题放入要使用常量的任何文件中。

第三:为什么你在这里使用预处理器定义?对于枚举来说,这似乎是一个完美的工作。然后你可以将它放入命名空间/结构中,以消除为它们添加前缀的需要(使用SM_)。或者您可以使用C ++ 11的新enum class,其行为与java的枚举非常相似。我会尽可能避免使用预处理器。因为它只是文本替换而且它不尊重任何范围等等,这使得容易陷入问题(例如用分号)。

答案 1 :(得分:3)

问题是yuu在#define之后有分号。这是唯一阻止你使用“常量”的东西,它们不是技术上的常量;它们是预处理器定义

逻辑上,C ++编译器通过预处理器运行程序文本,预处理器是一个文本过滤器,用于执行从#开始的指令。 #define指令指示预处理器查找其左侧部分的所有实例,并将其右侧部分逐字替换。在您的情况下,它包含分号,在替换后导致无效的表达式。

例如,

if (command == SM_DISCARD) ...

变为

if (command == 1005;) ...

这是一个错误,编译器将其报告为无效语法。

答案 2 :(得分:2)

使用#include <constants.h>或您的文件名包含此文件。此外,您不需要分号。 #defines是编译器对代码执行的文本替换。

答案 3 :(得分:0)

您不需要cpp个文件。包括标题就足够了。

预处理器使用后面的内容扩展您的定义。

SM_START将成为1001;

所以表达如下:

int x = SM_START;

将转换为

int x = 1001;;

这仍然是合法的。

但是这个分号可能会导致以下问题出现问题:

int x = SM_START * 10;

将扩展为:

int x = 1001; * 10;

这显然是非法的。

此外,不要将预处理程序指令与全局变量混淆。即使你可能不应该使用全局变量,使用#defines可能比定义class Global或仅使用namespace中分组的变量更糟糕。