头文件或 .cpp 中类变量的 C++ 声明?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28517555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 21:00:00  来源:igfitidea点击:

C++ Declaration of class variables in header or .cpp?

c++header-filesvariable-declaration

提问by Kefir

So far, I've been using classes the following way:

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

GameEngine.h declares the class as follows

GameEngine.h 声明类如下

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

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

    // Declaration of private methods
};

My GameEngine.cpp files then just implement the methods

我的 GameEngine.cpp 文件然后只实现这些方法

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

}

void GameEngine::run() {
    // stuff
}

However, I've recently read that variable declarations are not supposed to be in the header file. In the above example, that would be an inputManager and a, b, c.

但是,我最近读到变量声明不应该在头文件中。在上面的例子中,这将是一个 inputManager 和 a、b、c。

Now, I've been searching for where to put the variable declarations, the closest answer I found was this: Variable declaration in a header file

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

However, I'm not sure if the use of extern would make sense here; I just declare private variables that will only be used in an instance of the class itself. Are my variable declarations in the header files fine? Or should I put them elsewhere? If I should put them in the cpp file, do they go directly under the #include?

但是,我不确定在这里使用 extern 是否有意义;我只是声明了只在类本身的实例中使用的私有变量。我在头文件中的变量声明是否正常?还是我应该把它们放在别处?如果我应该将它们放在 cpp 文件中,它们是否直接放在 #include 下?

回答by ZaldronGG

Don't confuse a type's members with variables. A class/struct definition is merely describing what constitutes a type, without actually declaring the existence of any variables, anything to be constructed on memory, anything addressable.

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

In the traditional sense, modern class design practices recommend you pretend they are "black boxes": stuff goes in, they can perform certain tasks, maybe output some other info. We do this with class methods all the time, briefly describing their signatureon the .h/.hpp/.hxx file and hiding the implementation details in the .cpp/.cc/.cxx file.

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

While the same philosophy can be applied to members, the current state of C++, how translation units are compiled individually make this way harder to implement. There's certainly nothing "out of the box" that helps you here. The basic, fundamental problem is that for almost anything to use your class, it kind of needs to know the size in bytes, and this is something constrained by the member fields and the order of declaration. Even if they're private and nothing outside the scope of the type should be able to manipulate them, they still need to briefly know what they are.

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

If you actually want to hide this information to outsiders, certain idioms such as PImpl and inlined PImpl can help. But I'd recommend you don't go this way unless you're actually:

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

  1. Writing a library with a semi-stable ABI, even if you make tons of changes.
  2. Need to hide non-portable, platform-specific code.
  3. Need to reduce pre-processor times due to an abundance of includes.
  4. Need to reduce compile times directly impacted by this exposure of information.
  1. 编写具有半稳定 ABI 的库,即使您进行了大量更改。
  2. 需要隐藏不可移植的、特定于平台的代码。
  3. 由于包含大量内容,需要减少预处理器时间。
  4. 需要减少受此信息公开直接影响的编译时间。

What the guideline is actually talking about is to never declare global variables in headers. Any translation unit that takes advantage of your header, even if indirectly, will end up declaring its own global variable as per header instructions. Everything will compile just fine when examined individually, but the linker will complain that you have more than one definition for the same thing (which is a big no-no in C++)

该指南实际上谈论的是永远不要在标题中声明全局变量。任何利用您的标头的翻译单元,即使是间接的,最终都会根据标头说明声明自己的全局变量。当单独检查时,一切都会编译得很好,但链接器会抱怨你对同一件事有多个定义(这在 C++ 中是一个很大的禁忌)

If you need to reserve memory / construct something and bind it to a variable's name, always try to make that happen in the source file(s).

如果您需要保留内存/构造某些东西并将其绑定到变量的名称,请始终尝试在源文件中实现这一点。

回答by emlai

Class member variables mustbe declared in the class definition, which is usually in a header file. This should be done without any externkeywords, completely normally, like you have been doing so far.

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

Only variables that are notclass members and that need to be declared in a header file should be declared extern.

只应声明不是类成员且需要在头文件中声明的变量extern

回答by Michael Gazonda

As a general rule:

作为基本规则:

Variables that are to be used with many functions in the same class go in the class declaration.

与同一类中的许多函数一起使用的变量放在类声明中。

Temporary variables for individual functions go in the functions themselves.

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

It seems that InputManager inputManager;belongs in the class header.

似乎InputManager inputManager;属于类头。

int a, b, c;is harder to know from here. What are they used for? They looklike temporary variables that would be better off in the function(s) they're used in, but I can't say for sure without proper context.

int a, b, c;从这里更难知道。它们是做什么用的?它们看起来像是临时变量,在它们使用的函数中效果会更好,但如果没有适当的上下文,我不能肯定地说。

externhas no use here.

extern这里没有用。