2017-04-04 52 views
0

我目前正在從一本名爲Alex Allain的書中學習C++ - 跳入C++,並陷入了第21章。它詳細介紹了C++構建過程,並且明白了這一點,除了2部分:C++構建過程(包括)

第一:

「頭文件不應包含任何功能定義,如果我們增加了一個函數定義的頭文件,然後包括該頭文件到多個源文件,該功能的定義會顯示在鏈接時鏈接兩次,這會混淆鏈接器。「

二:

「永遠不要包括.cpp文件包括直接.cpp文件只會導致問題,因爲編譯器會編譯每個函數定義在.cpp文件複製到每一個目標文件。 ,鏈接器將會看到同一個函數的多個定義,即使你非常小心你是如何做到這一點的,你也將失去單獨編譯帶來的節省時間的好處。「

有人可以解釋他們嗎?

+2

我想你應該閱讀關於函數defenition和聲明之間的區別。它相當肯定它解決了你的問題。 –

回答

1

C++程序由一個或多個translation units創建。每個翻譯單元(簡稱TU)基本上是一個包含所有頭文件的源文件。當你創建一個目標文件時,你實際上正在創建一個TU。鏈接時,您將採用由編譯器創建的對象文件(TU),並將它們與庫鏈接以創建可執行程序。

一個程序只能有一個單一的定義的任何東西。如果您有多個定義,則鏈接時會出現錯誤。的定義可以像

int a; 

double b = 6.0; 

變量定義它也可以是一個函數定義,這是實際執行的功能。

您只能擁有一個定義的原因是因爲這些定義在程序加載執行時映射到內存地址。變量或函數不能同時存在於兩個地方。

這是您不應將源文件包含到其他源文件中的原因之一。這也是你不應該在頭文件中定義的原因,因爲頭文件可能包含在多個源文件中,因爲這會導致定義在多個TU中。


當然也有例外的這一點,像具有被標記爲inlinestatic的功能。但是解決了這個問題,因爲這些定義不是從TU輸出的,連接器也沒有看到它們。