什麼應該放在標頭檔案?何為外連線?

2021-06-08 15:55:01 字數 1577 閱讀 7136

**:

什麼應該放在標頭檔案裡

標頭檔案為相關宣告提供了乙個集中存放的位置。標頭檔案一般包含類的定義、列舉的定義、extern變數的宣告、函式的宣告、const int的定義、inline函式的定義。使用或者定義這些實體的檔案要包含適當的標頭檔案。  

標頭檔案用於宣告,而不用於定義

當設計標頭檔案時,記住定義和宣告的區別是很重要的。定義只可以出現一次,而宣告可以出現多次。下列語句是定義,所以不應該放在標頭檔案裡:

extern int ival = 10;           //有初始化,所以是定義

double fica_rate; //沒有extern關鍵字,所以也是定義

因為以上兩個語句都是定義(其實還因為全域性變數預設的連線型別是extern,即外連線),所以,當同乙個程式中有兩個或兩個以上檔案含有上述任乙個定義都會導致多重定義鏈結錯誤。

因為標頭檔案被設計用來包含在多個原始檔中,所以不應該含有變數或者函式的定義。

對於標頭檔案不應該含有定義這一規則,有三個例外:類定義、列舉的定義、值在編譯時就已知的const物件、inline函式。這些實體可以在多個原始檔中定義,只要每個原始檔中的定義是相同的。

在標頭檔案中定義這些實體,是因為編譯器需要它們的定義(不只是宣告)來產生**。例如:為了產生能定義和使用類物件的**,編譯器需要知道組成該型別的資料成員。同樣還需要知道能夠在這些物件上執行的操作。而類定義正好提供了這些資訊。

const物件(變數)預設是定義該變數的檔案的區域性變數,連線型別為內連線。

所以,當多個原始檔include包含同乙個含有const物件定義的標頭檔案時,不會產生多重定義的鏈結錯誤。這是因為,實質上每個包含該標頭檔案的原始檔都有了自己的const變數,都為它分配的儲存空間,其名稱和值都一樣。同時,因為const變數預設連線型別是內連線,所以不會產生多重定義的鏈結錯誤。

在大部分的編譯器實現中,編譯器都會用相應的常量表示式來替換對這些const變數的使用。所以,在實踐中不會有任何儲存空間用於儲存

用常量表示式初始化的const變數。

如果const變數不是用常量表示式初始化的,那麼它就不應該在標頭檔案中定義。它應該和其他的變數一樣,應該定義在乙個原始檔中並初始化,在標頭檔案中為它新增extern宣告,以便被多個檔案共享。

外連線

全域性變數、全域性函式預設是外連線的。

內連線

類定義、全域性常量、const物件(變數)、typedef型別、巨集定義

預設為內連線的。另外,定義時被顯示加上static關鍵字的全域性變數和全域性函式,具有檔案作用據,連線型別也為內連線。

預設為內連線的識別符號,如果顯示加上extern關鍵字,即變成外連線。

外連線識別符號的使用

在使用外連線的實體的時候,可以include其定義所在的檔案(錯誤的方法,產生鏈式錯誤:多重定義),還可以include其宣告所在的檔案。也可以採用第三種方法:直接在使用外連線實體的檔案中,直接對外連線實體進行一次extern宣告(若外連線實體型別為函式,則不用extern關鍵字,函式原型ok了)。

標頭檔案中應該寫什麼

通 過上面的討論,我們可以了解到,標頭檔案的作用就是被其他的.cpp 包含進去的。它們本身並不參與編譯,但實際上,它們的內容卻在多個 cpp 檔案中得到了 編譯。通過 定義只能有一次 的規則,我們很容易可以得出,標頭檔案中應該只放變數和函式的宣告,而不能放它們的定義。因為乙個標頭檔案的內容實際上是會...

標頭檔案中應該放些什麼2

標頭檔案中應該放些什麼2 字型 作為一般規則,應該把這些東西放入頭 h 檔案中 當宣告或巨集定義需要在多個檔案中共享時,尤其需要把它們放入標頭檔案中。特別是,永遠不要把外部函式原型 即外部函式宣告 放到 c 檔案中。另一方面,如果巨集定義或宣告為乙個 c 檔案私有,則最好留在 c 檔案中。標頭檔案中...

static變數放在標頭檔案的後果

問題 想用 static tlist g null 當全域性變數存煉表頭,但是可能在多處使用該全域性變數,listgethead 之類的引數用,所以就打算把static變數暴露出去,放在標頭檔案。最後出現了乙個問題,那就是往煉表存東西,當時用listgethead和listgetnext之類的傳全域...