【问题标题】:C++ Header and CPP includesC++ 头文件和 CPP 包括
【发布时间】:2012-02-12 04:27:35
【问题描述】:

快速提问。

我试图确定 C++,今天我花了几个小时处理双重定义链接器错误(“这已经被定义了!”),我终于意识到这是因为我有这样的布局:

  • main.cpp

    #include Dog.cpp
    
  • 狗.cpp

    #include Dog.h
    
  • 狗.h

    // (Dog class and prototype of test function)
    

现在我已经通过在 main.cpp 中包含 Dog.h 而不是 Dog.cpp 来解决这个问题。

通过包含.h文件,具有相同前缀的.cpp文件是否会与程序一起编译?

当程序运行时只包含 .h 而没有任何对 Dog.cpp 的引用时,我感到很震惊。我花了很长时间在谷歌上搜索,但没有任何答案能真正帮助我理解发生了什么。

编辑:我忘了补充说我在 .h 中进行了原型设计,并在 .cpp 中为类定义了函数,这就是给我“已定义”错误的原因。

【问题讨论】:

    标签: c++ header main


    【解决方案1】:

    包含不会自动导致编译,不会。

    事实上,实际的编译器根本看不到#include 语句。它被较早的步骤(称为预处理器)删除。

    如果您从未编译过 Dog.cpp 文件,我不确定它会如何构建。您是否使用该文件中定义的代码引用了任何对象?

    【讨论】:

      【解决方案2】:

      您没有指定如何编译它。如果您使用的是 IDE 并自动为项目添加了新的 .h 和 .cpp,那么它将自动编译和链接。

      使可执行文件运行有两个阶段:编译和链接。编译是代码被解释并翻译成较低级别代码的地方。链接是您使用的所有功能得到解决的地方。这是你得到重复函数错误的地方。

      【讨论】:

        【解决方案3】:

        通过包含 .h 文件,具有相同前缀的 .cpp 文件是否会与程序一起编译?当程序运行时只包含 .h 并且没有任何对 Dog.cpp 的引用时,我感到很震惊。

        没有。

        您的程序是分阶段构建的。

        • 对于编译阶段,每个翻译单元只需要声明(大致相当于一个解析#includes的.cpp文件)。声明甚至存在的原因首先是作为一种“承诺”,即稍后会找到完整的函数定义。

          g++ -c Dog.cpp               # produces `Dog.o`
          g++ -c main.cpp              # produces `main.o`
          
        • 对于链接阶段,符号在翻译单元之间进行解析。您必须将编译 Dog.cpp 和编译 main.cpp 的结果链接在一起(也许您的 IDE 正在为您执行此操作?),并且此链接过程会在它们之间找到所有正确的函数定义以生成最终的可执行文件。

          g++ Dog.o main.o -o program  # produces executable `program`
          

          (要么这样,要么你实际上还没有进入链接阶段,只有一个目标文件 (Dog.o);你不能执行它,部分原因是它没有所有的函数定义)

        两个阶段可以同时完成,用“速记”:

        g++ Dog.cpp main.cpp -o program  # compiles, links and produces executable
        

        【讨论】:

        • +1 啊..你打败了我,2阶段的过程正是OP需要知道和需要被告知的。我将删除我不完整的答案。
        • 没错,但也应该提到 dog.h 被包含两次。 #include 应该包含在:#ifndef ... #define 块中以阻止这种情况的发生。
        • 感谢您的回复。我使用的是 Code::Blocks,而不是使用我自己的 g++ 命令行。我只在 Windows 中使用过 IDE,所以 Linux(Ubuntu)对我来说非常不同,而且它的本质非常有趣,而且不是那么自动化。你能推荐一个解释.o文件的好地方吗?我什至不确定它们是什么:/
        • @vdbuilder:不,这是不正确的。每个翻译单元仅包含一次;因此,包含保护实际上不会产生任何影响(在链接器查看时它们甚至都不存在)。 (尽管无论如何这都是一种很好的做法,因为它在同一个 TU 中被多次包含。)
        • @ThomasuDesu:然后 Code::Blocks 知道您的“项目”中有哪些 .cpp 文件并自动为您执行上述操作。我现在还不会担心目标文件。但是,请让自己 a decent C++ book 解释构建过程。
        【解决方案4】:

        不,.cpp 文件不会自动编译。您可以手动执行此操作,创建一个 makefile,或使用在同一个项目中包含这两者的 IDE。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-07-05
          • 1970-01-01
          • 2017-01-16
          • 2012-02-08
          • 2018-10-01
          • 1970-01-01
          • 2020-03-11
          相关资源
          最近更新 更多