如何在没有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文件?有没有一种方法可以让我访问常量变量?

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

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

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

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

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

例如,

if (command == SM_DISCARD) ...

成为

if (command == 1005;) ...

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

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

您不需要cpp文件。包括页眉就足够了。

预处理器用后面的任何东西扩展你的定义。

SM_START将变为1001;

所以一个像这样的表达式

int x = SM_START;

将转换为

int x = 1001;;

这仍然是合法的。

但这个分号可能会导致类似的问题

int x = SM_START * 10;

将扩展为:

int x = 1001; * 10;

这显然是非法的。

此外,预处理器指令不能与全局指令混淆。尽管您可能不应该使用全局变量,但使用#defines可能比定义class Global或仅使用分组在namespace中的变量更糟糕。

相关内容

  • 没有找到相关文章

最新更新