代码之家  ›  专栏  ›  技术社区  ›  Kefir

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

  •  6
  • Kefir  · 技术社区  · 10 年前

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

    GameEngine.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。

    现在,我一直在寻找将变量声明放在何处,我找到的最接近的答案是: Variable declaration in a header file

    然而,我不确定在这里使用extern是否合理;我只是声明了仅在类本身的实例中使用的私有变量。头文件中的变量声明是否正常?还是我应该把它们放在其他地方?如果我应该将它们放在cpp文件中,它们是否直接放在#include下?

    3 回复  |  直到 7 年前
        1
  •  8
  •   ZaldronGG    10 年前

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

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

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

    如果您真的想向外人隐藏这些信息,某些习惯用法(如PImpl和内联PImpl)会有所帮助。但我建议你不要走这条路,除非你真的:

    1. 使用半稳定的ABI编写库,即使您做了大量更改。
    2. 需要隐藏不可移植的、特定于平台的代码。
    3. 由于包含大量内容,需要减少预处理时间。
    4. 需要减少直接受信息泄露影响的编译时间。

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

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

        2
  •  5
  •   Emil Laine    10 年前

    类成员变量 必须 通常在头文件中的类定义中声明。这应该在没有任何 extern 关键词,完全正常,就像你一直在做的那样。

    只有 需要在头文件中声明的类成员和 外部 .

        3
  •  3
  •   Michael Gazonda    10 年前

    作为一般规则:

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

    单个函数的临时变量在函数本身中。

    看起来 InputManager inputManager; 属于类标题。

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

    extern 在这里没有用。