如何在没有cpp文件的情况下使用头文件
我是一名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 文件吗?有没有办法让我访问常量变量?
I am a java developer, but I have had to learn C++ recently and I am confused about some things. What I would like to do is create a 'global' header file, which has a list of #define variables which will be constant throughout the suite I am creating. I created the header file, and I added some variables
#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
My problem is that I can't access these...
I have included the header file where I need it, but there is no way for me to access the constants inside of it. Do I Have to have a .cpp file? is there a way for me to access the constant variables?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
第一:您不应该将分号放在
#define
的末尾。#define
是一个预处理器指令,这意味着它基本上用内容替换定义的名称。因此,如果您执行类似 int a = SM_STOP + 1; 的操作,它将被预处理为 int a = 1003; + 1; 与您的代码,这不是您想要的。其次:标头通常不会自行编译,而仅用于包含到
*.cpp
文件或其他标头中(其中#include
再次是文本替换)。因此,是的,你需要在某个地方有一个 .cpp 文件(不完全是,首先你可以选择不同的扩展名,其次你甚至可以给编译器一个标头作为编译单元,但我会建议不要这样做,至少在您知道自己在做什么之前)。但是,您不需要为常量提供.cpp
文件,只需将标头#include
放入您想要在其中使用常量的任何文件中。第三:为什么在这里使用预处理器定义?这对于枚举来说似乎是一项完美的工作。然后,您可以将其放入命名空间/结构中,从而无需为它们添加前缀(使用
SM_
)。或者您可以只使用 C++11 的新枚举类
,它的行为与 java 的枚举非常相似。我会尽可能避免使用预处理器。因为它只是简单的文本替换,并且不考虑任何范围等,这使得很容易遇到问题(例如分号)。First: You shouldn't put the semicolons at the end of the
#define
.#define
is a preprocessor directive, meaning that it basically does text replacement of the defined name with the content. So if you do something likeint a = SM_STOP + 1;
it would be preprocessed toint a = 1003; + 1;
with your code, which is not what you want.Second: Headers are generally not compiled themselves but only for inclusion into
*.cpp
files or other headers (where#include
is once again a text substitution). Therefore, yes you need to have a.cpp
file somewhere (well not exactly, first of all you can choose a different extension and second you could even give the compiler a header as compile unit, but I would advise against it, at least until you know what you are doing). However you do not need to have a.cpp
file for your constants, just#include
your header into whatever file you want to use the constants in.Third: Why are you using preprocessor defines here? This seems to be like a perfect job for an enum. Then you could put it into a namespace/struct for removing the need to prefix them (with
SM_
). Or you could just use C++11's newenum class
, which behaves much like java's enums. I would avoid preprocessors wherever possible. Since it is simply text replacement and it doesn't respect any scoping and such, which makes it easy to get into problems (like with your semicolons).问题是 yuu 在
#define
之后有分号。这是唯一阻止您使用“常量”的因素,这些“常量”在技术上并不是常量;它们是预处理器定义。从逻辑上讲,C++ 编译器通过预处理器(执行以
#
开始的指令的文本过滤器)运行程序文本。#define
指令指示预处理器查找其左侧部分的所有出现位置,并用其右侧部分逐字替换它们。在您的情况下,它包含分号,导致替换后表达式无效。例如,
变为
This is an error,编译器将其报告为无效语法。
The problem is that yuu have semicolons after
#define
. This is the only thing preventing you from using your "constants", which are not technically constants; they are preprocessor definitions.Logically, the C++ compiler runs the text of your program through a preprocessor, a text filter that executes the directives starting in
#
. The#define
directive instructs preprocessor to find all occurrences of its left part, and replace them verbatim with its right part. In your case, it includes semicolons, resulting in invalid expressions after replacement.For example,
becomes
This is an error, and the compiler reports it as invalid syntax.
使用
#include
或任何文件名来包含此文件。另外,您不需要分号。 #defines 是编译器对代码进行的文本替换。Use
#include <constants.h>
or whatever your filename is to include this file. Also, you don't need the semi-colons. #defines are text replacements done on the code by the compiler.您不需要
cpp
文件。包括标题就足够了。预处理器用它后面的内容扩展你的定义。
SM_START
将变为1001;
因此,像这样的表达式:
将转换为
仍然合法的。
但是这个分号可能会导致麻烦,比如:
which 将被扩展为:
这显然是非法的。
另外,不要将预处理器指令与全局变量混淆。即使您可能不应该使用全局变量,但使用
#defines
可能比定义class Global
或仅使用分组在namespace
中的变量更糟糕>。You don't need a
cpp
file. Including the header is enough.The preprocessor expands your defines with whatever is after it.
SM_START
will become1001;
So an expression like:
will translate to
which is still legal.
But that semicolon could lead to trouble in something like:
which will be expanded to:
which is obviously illegal.
Also, preprocessor directives are not to be confused with globals. Even though you probably shouldn't be using globals, using
#defines
is probably worse than defining aclass Global
or just using variables grouped in anamespace
.