我是一名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文件?我有办法访问常量变量吗?
答案 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
中分组的变量更糟糕。