2012-03-22 88 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文件。你不需要擔心任何事情。

希望這會有所幫助。