【问题标题】:Difference between C++ filesC++ 文件之间的区别
【发布时间】:2012-04-07 09:00:58
【问题描述】:

我刚刚开始了图形化 C++ 课程,但无法大致了解它的概况。 我们有一些起始代码,两个文件;一种是“C++ Source”类型,另一种是“C/C++ Header”类型。 它应该是一个用颜色填充屏幕的图形程序。 另外,我们正在使用一些自定义库,例如 SDL 和 GLM,在与这两个文件相同的文件夹中,有一个名为 gml 的文件夹和许多子文件夹,我不会进入。

我已经下载了 mingw、cmake 和 Visual Studio 11 beta for c++。

我尝试过制作一个普通的 Win32 程序以及图形部分的表单应用程序,但编译时总是出错。

我的问题:您应该如何处理 C++ 文件?我刚习惯了java,打开.java文件并粘贴到你的IDE中很容易,处理C++让我很困惑。

【问题讨论】:

  • 你肯定需要去找你的老师讨论这个问题,建立一个项目会涉及到更多可以在这里简单回答的问题。如果您遇到特定问题,可能是奇怪的错误消息,我们可以提供帮助。
  • “句柄”是什么意思?
  • 如果课程不包括 C++ 基础知识,我推荐a good book
  • 我最好的建议是使用没有 IDE 的裸控制台编译器来理解您的要求。但我觉得这可能不是最适合你的解决方案。
  • @OliCharlesworth - 你只需要一个足够长的驳船。 OP,习惯“未解决的外部”这个短语。

标签: c++


【解决方案1】:

嗯...从哪里开始...

在其他语言中发生在幕后的事情在 C++ 中更为明显。从 C++ 获取二进制文件(例如可执行文件)的过程包括首先编译源代码(其中有子步骤,但编译器会处理它们)以获取目标文件,然后由链接器链接目标文件以生成一个二进制文件。

理论上,您可以简单地 #include 一个项目中的所有 cpp 文件,然后将它们全部编译并“链接”(虽然没有什么可链接的)但这需要很长时间,更重要的是,在可能会耗尽编译器可用内存的复杂项目。

因此,我们将项目拆分为编译单元,按照惯例,.cpp 文件代表单个编译单元。编译单元是项目中经过编译以生成一个目标文件的部分。尽管编译单元是分开编译的,但它们之间必须有一些代码是通用的,这样每个编译单元中的一段代码才能使用其他代码实现的功能。 .h 文件通常用于此目的。事情基本上是在其中声明(有点宣布)的,因此每个编译单元都知道当它是生成二进制文件的链接过程的一部分时会发生什么。

还有图书馆的问题。你可以在图书馆里找到两种主要的东西;

  • 已经实现的功能,以二进制文件的形式提供给您,包括几乎可以运行的 CPU 指令(但它们必须插入正确的位置)。此表单附有 .h 文件,让您的 .cpp 文件知道库中的内容。
  • 第二种是直接在 .h 中实现的功能 文件。是的,这在特殊情况下是可能的。有案例, 实施必须(弱者必须)伴随 声明(内联函数、模板类型等)。

第一种类型有两种形式:一个“静态库”(Windows 中的 .lib,Linux 中的 .a),它进入您的可执行文件并在链接期间成为它的一部分,以及一个“动态库”,即暴露给你的二进制文件(所以它知道),但这并没有成为它的一部分。因此,您的可执行文件将在运行时查找该动态库(Windows 中的 .dll 文件和 linux f.x 中的 .so 文件)。

因此,为了让您的 .cpp 文件能够接收来自库的服务,他们必须 #include 他们的 .h 文件,以了解其中的内容。稍后,在链接期间,您必须向链接器显示在哪里(文件系统中的路径)以找到这些库的二进制组件。最后,如果库是动态的,则 .dll(或 .so 等)必须在运行时可访问(例如,将它们保存在同一文件夹中)。

在编译编译单元时,您必须告诉编译器在哪里可以找到 .h 文件。否则,它将看到的只是#include <something.h>,并且它不知道在哪里可以找到该文件。使用 gcc,您可以使用 -I 选项告诉编译器。请注意,您只需告诉文件夹。同样重要的是,如果 include 指令看起来像 #include<somefolder/somefile.h>,则不应在路径中包含 somefolder。所以调用看起来像:

g++ mycompilationunit.cpp -IPATH/TO/THE/INCLUDED/FILES -IPATH/TO/OTHER/INCLUDED/FILES -c

-c 选项告诉编译器它不应该尝试仅从该编译单元生成可执行文件,因此它会创建一个 .o 文件,以便稍后与其他文件链接。由于我们没有告诉它输出文件名,它会吐出mycompilationunit.o

现在我们想要生成我们的二进制文件(您可能想要一个可执行文件,但您也可能想要创建自己的库)。所以我们必须告诉链接器进入二进制文件的所有内容。所有目标文件以及所有静态和动态库。所以,我们说:(注意这里的 g++ 也充当了链接器)

g++ objectfile1.o objectfile2.o objectfile3.o -LPATH/TO/LIBRARY/BINARIES -llibrary1 -llibrary2 -o myexecutable

这里,-L 选项在示例中是不言自明的。 -l 选项告诉要查找哪些二进制文件。如果在路径上找到静态库和动态库,链接器将同时接受它们,如果两者都找到,它将选择一个。请注意, -l 之后的不是完整的二进制名称。例如,在 linux 中,库名称采用 liblibrary.so.0 的形式,但在链接器命令中它们被称为 -llibrary。 finally -o 告诉编译器给你的可执行文件起什么名字。您需要一些其他选项来 f.x。创建一个动态库,但您现在可能不需要了解它们。

【讨论】:

  • 哇,感谢您的提醒。我从没想过有人会花那么多时间来解释,这是一个非常好的答案——就像一堂教育课:-)关于“幕后”我现在也真的这么觉得。我将通过一些 c++ 教程来掌握它,只是你需要指导输出流这一事实让我认为 c++ 与 java 相比需要更多的“指令”。
【解决方案2】:

What is the difference between a .cpp file and a .h file?

看看这个答案。快速谷歌搜索也解释了一点。

几乎 .h(头)文件是声明,而 .cpp(源)文件是定义。可以将两个文件合并为一个 .cpp 文件,但随着项目变得越来越大,它变得烦人且几乎不合理。

希望对您有所帮助。

【讨论】:

    【解决方案3】:

    在 C++ 中,有函数声明(函数签名)和函数定义(实际代码)的概念。

    头文件 (*.h) 包含函数和类的声明。源文件(*.cpp、*.c++、*.C)包含定义。

    可以使用#include 指令将头文件包含在源文件中。

    在 C++ 中定义类时,通常只包含成员函数的声明(Java 术语中的方法),并将类定义放入头文件中。包含每个函数主体的成员函数定义通常放在类定义之外并放入源文件中。

    一般来说,最好的办法是买一本关于 C++ 或 C 的书,并查看一些示例代码。

    【讨论】:

      【解决方案4】:

      头文件 (.h) 应该包含类、方法和变量的定义。源文件 (.cpp) 将包含代码。因此,在您的 .cpp 文件中,您需要将头文件包含为 #include "header-file-name.h"

      然后使用g++编译.cpp文件。确保 .h 文件的路径正确。

      如果您使用的是 CodeBlocks 或 Visual Studio,那么只需编译项目并运行即可为您完成所有工作。您还可以从那里添加 .h 或 .cpp 文件。您无需担心任何事情。

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-10
        • 2011-01-29
        • 1970-01-01
        • 2013-11-07
        • 2012-02-17
        • 1970-01-01
        • 2020-10-17
        • 2010-10-23
        相关资源
        最近更新 更多