2012-02-08 85 views
1

我是一名java开发人员,但最近我不得不学习C++,并对某些事情感到困惑。我想要做的是创建一个'全局'头文件,其中包含#define变量列表,这些变量在我创建的套件中将保持不变。我创建的头文件,我添加了一些变量如何在没有cpp文件的情况下使用头文件

#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文件?有没有办法让我访问常量变量?

+1

除了以下可爱的评论,如果你可以避免它,请不要使用#define作为简单的数字常量。如果你改为'const int SM_START = 1001;'等等 – 2012-02-08 15:24:38

回答

4

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

第二:标题通常不会自行编译,但只能包含在*.cpp文件或其他标题中(其中#include再次是文本替换)。因此,你需要在某个地方有一个.cpp文件(不完全是这样,首先你可以选择一个不同的扩展名,其次你甚至可以给编译器一个头部作为编译单元,但我会建议不要这样做,至少在你知道之前你在做什么)。但是你不需要为你的常量有一个.cpp文件,只需要将#include头插入你想要使用的常量文件中。

第三:为什么你在这里使用预处理器定义?这似乎是一个枚举的完美工作。然后你可以把它放到一个命名空间/结构中去除需要的前缀(用SM_)。或者你可以使用C++ 11的新的enum class,它的行为很像javas枚举。我会尽可能地避免预处理器。因为它只是简单的文本替换,所以它不考虑任何范围界定等,这使得它很容易陷入问题中(如使用分号)。

2

使用#include <constants.h>或任何您的文件名将包括此文件。另外,你不需要分号。 #defines是由编译器在代码上完成的文本替换。

+1

“constants.h”,而不是,你可以得到相同的效果和更容易的错误信息 - 如果你把它们放在< >,并且我已经使用了多个可能会错误此@TomTanner同意的 – 2012-02-08 15:08:32

+0

。 – Sid 2012-02-08 15:14:06

+0

@TomTanner尽管您可以使用-I/path/to/include来规避这种情况。 – Sid 2012-02-08 15:15:55

3

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

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

例如,

if (command == SM_DISCARD) ... 

变得

if (command == 1005;) ... 

这是一个错误,并且编译器报告为无效的语法。

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中的变量更差。

+0

那么,我正在努力做好实践?这个想法是,这个'常量'将被制成一个库,因为不止一个进程需要访问它。如果有更好的方法来做到这一点,请赐教,因为我不知道我做的是对的。 – PTBG 2012-02-08 15:17:43

+0

@PTBG不是真的。 1.全局变量*通常*不好。 2.如果使用全局变量,则将它们作为静态常量成员放入类中或作为名称空间中的外部变量。 – 2012-02-08 15:18:52

相关问题