C++文件之间的区别

Yam*_*ron 1 c++

我刚刚开始了一个图形化的C++课程,但是我很难弄清楚它是如何构建的.我们得到了一些启动代码,两个文件; "C++ Source"类型之一和"C/C++ Header"中的另一个.它应该是一个用彩色填充屏幕的图形程序.另外,我们正在使用一些自定义库,如SDL和GLM,在这两个文件所在的文件夹中有一个名为gml的文件夹和子文件夹的加载,我不会进入.

我已经为c ++下载了mingw,cmake和Visual Studio 11 beta.

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

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

eno*_*ram 6

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

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

从理论上讲,你可以简单地#include将项目中的所有cpp文件编译,然后将它们全部编译并"链接"(尽管没有任何内容可以链接),但这需要很长时间,更重要的是,在复杂的项目中可能耗尽内存可供编译器使用.

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

图书馆也存在问题.你可以在图书馆找到两种主要的东西;

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

第一种类型有两种形式:一个"静态库"(windows中的.lib,linux中的.a),输入你的可执行文件并在链接过程中成为它的一部分,以及一个暴露给你的"动态库"二进制(所以它知道它),但这不会成为它的一部分.因此,您的可执行文件将在运行时查找该动态库(Windows中的.dll文件和linux fx中的.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
Run Code Online (Sandbox Code Playgroud)

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

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

g++ objectfile1.o objectfile2.o objectfile3.o -LPATH/TO/LIBRARY/BINARIES -llibrary1 -llibrary2 -o myexecutable
Run Code Online (Sandbox Code Playgroud)

这里,-L选项在示例中是自解释的.-l选项告诉要查找的二进制文件.如果链接器在路径上找到它们,它将接受静态和动态库,如果它找到它们,它将选择一个.请注意,-l之后的内容不是完整的二进制名称.例如,在linux库名称中采用表单,liblibrary.so.0但它们在链接器命令中称为-llibrary.最后-o告诉编译器为您的可执行文件指定了什么名称.您需要一些其他选项来创建动态库,但您现在可能不需要了解它们.