首先,以解決您的第一次調查:
當您在.H文件中看到這一點:
#ifndef FILE_H
#define FILE_H
/* ... Declarations etc here ... */
#endif
這被包括防止頭文件從的預處理技術多次,由於各種原因,這可能是有問題的。在編譯項目期間,每個文件(通常)都會被編譯。簡單來說,這意味着編譯器將採取您的。cpp文件,打開文件#included
,將它們全部拼接成一個海量文本文件,然後進行語法分析,最後將其轉換爲中間代碼,優化/執行其他任務,最後生成彙編輸出目標架構。因此,如果一個文件在.cpp文件下多次執行#included
,編譯器會將其文件內容追加兩次,因此如果該文件中有定義,將會收到編譯器錯誤,告訴您重新定義了一個變量。當文件由編譯過程中的預處理器步驟處理時,第一次到達其內容時,前兩行將檢查是否已爲預處理器定義了FILE_H
。如果沒有,它將定義FILE_H
並繼續處理它和#endif
指令之間的代碼。預處理器下次看到該文件的內容時,對FILE_H
的檢查將爲false,因此它將立即掃描到#endif
並在其後繼續。這可以防止重新定義錯誤。
,並解決你的第二個問題:
在C++編程,因爲我們分開發展成兩個文件類型通用做法。其中一個擴展名爲.h,我們稱之爲「頭文件」。它們通常提供函數,類,結構體,全局變量,類型定義,預處理宏和定義等的聲明。基本上,它們只是爲您提供有關代碼的信息。然後我們有擴展名爲.cpp,我們稱之爲「代碼文件」。這將爲這些函數,類成員,需要定義的任何結構成員,全局變量等提供定義。因此,.h文件聲明代碼,並且.cpp文件實現該聲明。由於這個原因,我們一般在編譯期間將每個文件編譯成一個對象,然後鏈接這些對象(因爲您幾乎從不會看到一個文件包含另一個.cpp文件)。
如何解決這些外部問題是鏈接器的工作。當您的編譯器處理main.cpp時,它將通過包括class.h獲取class.cpp中的代碼的聲明。它只需要知道這些函數或變量是什麼樣的(這是聲明給你的)。所以它將你的文件編譯成一個目標文件(稱爲main.obj)。同樣,class.cpp被編譯成class.obj文件。爲了生成最終的可執行文件,調用鏈接器將這兩個目標文件鏈接在一起。對於任何未解析的外部變量或函數,編譯器會在發生訪問的地方放置一個存根。然後鏈接程序將取出該存根,並在另一個列出的目標文件中查找代碼或變量,如果找到它,它將來自兩個目標文件的代碼合併到一個輸出文件中,並將該存根替換爲該函數的最終位置,或者變量。這樣,main.cpp中的代碼可以調用函數並使用class.cpp中的變量如果僅在他們聲明瞭class.h。
我希望這是有幫助的。
「導入」可能不是你想在這裏使用的詞。包括。 – 2010-07-14 13:59:23
在C++中,文件和類之間沒有1對1的關聯。你可以根據需要將多個類放入一個文件中(甚至可以將一個類分成幾個文件,儘管這很少有用)。因此宏應該是'FILE_H',而不是'CLASS_H'。 – sbi 2010-07-14 14:12:03
看我的[包括警衛建議](http://stackoverflow.com/questions/1744144/include-guards/1744302#1744302)。 – 2010-07-15 04:13:59