2012-03-22 102 views
1

我刚刚开始了一个图形化的C++课程,我有问题想要了解它是如何实现的。 我们得到了一些起始代码,两个文件; “C++ Source”类型之一和“C/C++ Header”之一。它应该是一个用颜色填充屏幕的图形程序。 此外,我们使用一些自定义库,如SDL和GLM,在与这两个文件相同的文件夹中有一个名为gml的文件夹和负载的子文件夹,我不会介入。C++文件之间的区别

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

我试过制作一个普通的Win32程序,也是一个图形部分的窗体应用程序,但是它在编译时总是出错。

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

+2

你一定要去找你的老师,建立一个项目将会涉及更多的东西,这里可以简单地回答。如果遇到特定问题,也许会出现一条奇怪的错误消息,我们可以在那里帮助。 – Collin 2012-03-22 18:37:57

+0

你是什么意思的“处理”? – 2012-03-22 18:38:13

+2

如果该课程不包括C++基础知识,我会推荐[一本好书](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。 – 2012-03-22 18:38:17

回答

6

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

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

从理论上讲,您可以简单地将项目中的所有cpp文件整合在一起并“链接”(虽然没有链接),但这需要很长时间,更重要的是,在复杂可能会耗尽编译器可用内存的项目。

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

这也是图书馆的问题。你可以在图书馆找到两种东西,

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

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

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

在编译你的编译单元时,你必须告诉编译器在哪里找到.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。最后-o告诉编译器什么名字给你的可执行文件。你需要一些其他的选项f.x.创建一个动态库,但你现在可能不需要知道它们。

+0

哇,谢谢你的抬头。我从来没有想过有人会花费那么多时间来解释,这是一个非常好的答案 - 就像一个教育课:-)关于“幕后花絮”我现在真的感觉到这一点。我将通过一些C++教程来了解它,只是需要指导输出流的事实让我觉得与java相比,C++需要更多的“指令”。 – 2012-03-22 19:22:50

+0

当然:)我们会尽力避免做我们应该做的事情...... – enobayram 2012-03-22 19:31:08

2

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

看这个答案。另外一个快速的谷歌搜索也解释了一下。

很多.h(头文件)文件是declerations和.cpp(源)文件是定义。将两个文件合并成一个.cpp文件是可能的,但随着项目变得越来越大,它变得烦人而且几乎不合理。

希望有所帮助。

1

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

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

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

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

一般来说,这里要做的最好的事情是拿一本关于C++或C的书,并看看一些示例代码。

0

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

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

如果您使用的是CodeBlocks或Visual Studio,那么编译项目和运行将为您做所有事情。您也可以从那里添加.h或.cpp文件。你不需要担心任何事情。

希望这会有所帮助。