【问题标题】:Linking files in C++在 C++ 中链接文件
【发布时间】:2015-10-28 23:18:10
【问题描述】:

在休息 2 年后,我正在尝试通过开发一个基本的纸牌游戏程序来更新我的基本 C++ 技能。所以我创建了 3 个对象:deck、hand 和 card。一切都运行良好,直到我尝试定义一个全局常量牌组供整个程序使用并且一切都搞砸了(牌组应该是按顺序排列的所有 52 张牌,并且永远不会改变)。我正在尝试弄清楚如何将以下文件链接在一起:

main.cpp
deck.h
deck.cpp
hand.h
hand.cpp
card.h
card.cpp

我需要在哪里包含以及在哪里以及如何定义要在整个程序中使用的全局套牌?我把我现有的代码弄得一团糟,试图将所有东西都包含在内,但现在没有任何东西可以正确编译。谢谢!

【问题讨论】:

  • 一些错误输出对于任何有动力解决您的问题的人来说都是无价的。
  • 在没有任何实际线索的情况下,我预测您在标题中声明全局卡组时忘记添加extern。在这种情况下,每个包含该头文件的源文件都会认为他们拥有一个私有的卡组静态实例,而不是意识到他们需要稍后链接到它。

标签: c++ static-linking


【解决方案1】:

全局变量(或常量)声明在文件的顶部,在包含的下方,但在任何代码上方。

所以对于这个例子,我会这样写:

#include <iostream>
#include <deck.h>
#include <hand.h>
#include <card.h>

extern deck ... // If we want to use the deck constant anywhere in our program

int main ()
{
    ...
}

请注意,我在这里假设甲板是非常数的(我认为这不会造成问题)。 但是如果你绝对需要使用全局常量,你可以创建一个新文件,例如命名为 deckConstant.cpp 然后在这个文件中写入以下内容:

namespace myGlobalConstant
{
    extern const deck ... // put the name of the constant you want
}

当然还要创建文件deckConstant.h:

#ifndef DECKCONSTANT_H
#define DECKCONSTANT_H

namespace myGlobalConstant
{
    extern const deck ...
}
#endif

然后在 main.cpp 文件中添加:

#include <deckConstant.h>
using namespace myGlobalConstant

我希望我正确理解了这个问题。

【讨论】:

    【解决方案2】:

    要回答有关全局的问题,您可以在 deck.h 中将其声明为 extern(我假设这在您的程序中有意义)并在 deck.cpp 中定义。

    例如:

    甲板.h

    extern Card GLOBAL_DECK[52];
    

    deck.cpp

    Card GLOBAL_DECK[52];
    

    现在对于使用全局变量,这是一种更好的方法来避免全局变量,并将引用传递给位于更高范围内的对象,或者在堆上创建对象并传递指向它的指针或引用(但你完成后记得删除它)。

    对于关于在哪里需要包含的问题,您应该像这样将每个标头包装在包含保护中(将 HEADER_NAME 替换为标头文件名,例如 hand.h 变为 HAND_H:

    #ifndef HEADER_NAME
    #define HEADER_NAME
    
    header contents
    
    #endif //Some people like to put HEADER_NAME here but it isn't really necessary 
    //unless you are using a lot of precompiler directives, which you shouldn't be 
    

    然后将标题包含在需要它们的文件中。手牌和套牌都需要卡片,其他一切都取决于您如何使用它们。由于您没有提到您正在使用哪个编译器/工具集,我无法给您具体说明。但我会自己编译它们,并包含编译每个文件所需的内容。你可能会遇到循环依赖,也就是说A需要B编译,需要A编译(或者更长的链,但最终会变成循环),你需要研究前向声明,可能需要使用引用和指针来解决,或更改您的设计。

    然后您需要将目标文件链接在一起以生成可执行文件。如果您使用像 Visual Studio 或 code::blocks 这样的集成 IDE,它会为您完成,但您可能需要找出您的链接器是什么,或者如果您使用的是像 eclipse 这样的通用 IDE,您可能需要设置一个。

    【讨论】:

      【解决方案3】:

      对于deck,只需在main.cpp 中定义它。它可以通过引用其他类中需要操作它的任何函数来传递。至于标题,#include 仅是当前源文件所需的标题。包含标头保护也是一个好主意,因此您不必担心引用标头的次数。

      编辑

      extern 在另一个答案中被提及。如果您实际上是在定义一个全局对象,这是必要的。关于全局变量的看法不一。我在纯 C++ 中并不经常看到它。

      【讨论】:

        猜你喜欢
        • 2017-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-10
        • 2020-04-03
        • 1970-01-01
        相关资源
        最近更新 更多