C++ C++;在header或.cpp中声明类变量?

C++ C++;在header或.cpp中声明类变量?,c++,header-files,variable-declaration,C++,Header Files,Variable Declaration,到目前为止,我一直以以下方式使用类: h声明类如下 class GameEngine { public: // Declaration of constructor and public methods private: InputManager inputManager; int a, b, c; // Declaration of private methods }; 然后,我的GameEngine.cpp文件只需实现这些方法 #include "___

到目前为止,我一直以以下方式使用类:

h声明类如下

class GameEngine {
public:
    // Declaration of constructor and public methods

private:
    InputManager inputManager;
    int a, b, c;

    // Declaration of private methods
};
然后,我的GameEngine.cpp文件只需实现这些方法

#include "____.h"    
GameEngine::GameEngine() {

}

void GameEngine::run() {
    // stuff
}
然而,我最近读到,变量声明不应该出现在头文件中。在上面的示例中,这将是一个inputManager和a、b、c

现在,我一直在寻找变量声明的位置,我找到的最接近的答案是:

然而,我不确定在这里使用extern是否有意义;我只声明私有变量,这些变量将只在类本身的实例中使用。头文件中的变量声明可以吗?或者我应该把它们放在别处?如果我把它们放在cpp文件中,它们是否直接放在#include?

类成员变量必须在类定义中声明,而类定义通常在头文件中。这应该在没有任何
extern
关键字的情况下完成,完全正常,就像您到目前为止所做的那样

作为一般规则,只有非类成员且需要在头文件中声明的变量才应声明为
extern

将与同一类中的多个函数一起使用的变量放入类声明中。

单个函数的临时变量进入函数本身。

似乎
InputManager-InputManager属于类标题

inta、b、c更难从这里了解。它们是用来干什么的?它们看起来像临时变量,在使用它们的函数中会更好,但如果没有适当的上下文,我不能肯定


extern
在这里没有用处。

不要将类型的成员与变量混淆。类/结构定义只是描述构成类型的内容,而没有实际声明任何变量的存在、要在内存上构造的任何内容、任何可寻址的内容

在传统意义上,现代课堂设计实践建议你假装它们是“黑匣子”:东西进入,它们可以执行某些任务,可能输出一些其他信息。我们一直使用类方法来实现这一点,在.h/.hpp/.hxx文件中简要描述它们的签名,并在.cpp/.cc/.cxx文件中隐藏实现细节

同时,同样的哲学可以应用于成员,C++的当前状态,翻译单位如何单独编译,使这种方式更难实现。在这里,当然没有什么“开箱即用”的东西可以帮助你。基本的问题是,对于几乎所有要使用类的东西,它都需要知道以字节为单位的大小,这是受成员字段和声明顺序限制的。即使它们是私有的,并且类型范围之外的任何东西都不能操纵它们,它们仍然需要简单地知道它们是什么

如果您真的想向外界隐藏这些信息,某些习惯用法,如PImpl和内联PImpl可以提供帮助。但我建议你不要走这条路,除非你真的:

  • 使用半稳定的ABI编写库,即使您进行了大量更改
  • 需要隐藏不可移植的、特定于平台的代码
  • 由于包含的内容丰富,需要减少预处理器时间
  • 需要减少直接受信息暴露影响的编译时间
  • 该指南实际上讨论的是永远不要在标题中声明全局变量。任何利用标题的翻译单元,即使是间接的,最终也会按照标题说明声明自己的全局变量。当单独检查时,一切都可以编译,但是链接器会抱怨您对同一事物有多个定义(这在C++中是一个很大的禁忌)


    如果您需要保留内存/构造某些内容并将其绑定到变量名,请始终尝试在源文件中执行此操作。

    “变量声明不应在头文件中”。。。。什么?成员变量必须与类声明一起声明。如果该变量要全局使用,则extern将进入标头,并且在某个.cpp文件中定义该变量一次。如果它们是内部使用的全局变量,那么它们进入.cpp。如果它们在逻辑上是类的一部分,则将它们设为成员变量。变量声明和成员变量声明是不同的。此外,非成员变量的定义会给你带来问题,而不是声明。你的意思是使用?我不知道你在那里读到了什么。我试过了,但再也找不到原始声明。事实上,它就在某个地方,但由于我试图寻找答案,我的历史记录太满了,无法再次找到它。对我来说,这听起来像是一个普遍的说法,即在.h文件中声明变量是糟糕的编程风格;但是,考虑到您的反应,我可能误解了它;只是一个声明,还是会尝试保留内存?我最初想在GameEngine的构造函数中初始化inputManager,但是,它不会编译,因为inputManager没有默认构造函数。(没有默认构造函数,但我也没有在任何地方调用没有参数的构造函数。)这让我很惊讶,因为我只是想声明变量的存在性,但似乎在声明时它需要一个默认构造函数。就像在类声明中一样,您声明它包含一个完整的InputManager,但到目前为止实际上还没有构建任何东西。一旦您在运行时通过构造函数创建GameEngine对象,它就会有一部分字节专门用于存储整个InputManager。犯人