1. 程式人生 > >C++標頭檔案的重定義問題以及標頭檔案互相包含問題

C++標頭檔案的重定義問題以及標頭檔案互相包含問題

  有的人將重複編譯,重複包含與重複定義弄混,比如:定義一個類,在例項化它之前並不產生記憶體開銷;這與基本型別有所區別。

明明在標頭檔案使用了#pragma once#ifndef...#define...#endif,為什麼在標頭檔案定義了一個全域性變數,還會出現重複定義的錯誤,為什麼標頭檔案裡的類的定義卻不會報錯?

首先:

   #pragma once;#ifndef...#define...#endif這個只能解決重複包含,防止該標頭檔案在一個.cpp檔案裡二次包含或者二次編譯,但無法解決重複定義的

重複包含是編譯期間的------------------------------------------------------


重複定義是連結期間的------------------------------------------------------

解決標頭檔案相互包含的問題---超前引用:是解決包含了一次不能包含第二次的問題,標頭檔案互相包含只能編譯一次的問題。
   類A和類B需要彼此互相引用,這樣必然有一個類會先被編譯,而另外一個類後被編譯,這樣在先被編譯的類引用後被編譯的類的時候,就導致了所謂的超前引用。(就需要在先編譯的類檔案裡聲明後編譯檔案的類。)

1)、使用類宣告  在超前引用一個類之前,首先用一個特殊的語句說明該識別符號是一個類名,即將被超前引用。其使用方法是:
            a)  用class ClassB;宣告即將超前引用的類名


            b)  定義class ClassA
            c)  定義class ClassB;
            d)  編制兩個類的實現程式碼。

  ClassA和ClassB分別有自己的標頭檔案和cpp檔案,這種方法需要演變成:
            a) 分別定義ClassA和ClassB,並在cpp檔案中實現之
            b) 在兩個標頭檔案的開頭分別用class ClassB;和class ClassA;宣告對方
            c) 在兩個cpp檔案中分別包含另外一個類的標頭檔案
     NOTE:這種方法切記不可使用類名來定義變數和函式的變數引數,只可用來定義引用或者指標。


 2)、使用全域性變數
     由於全域性變數可以避免超前引用,不用贅述。我的習慣是,把類物件的extern語句加在該類標頭檔案的最後,大家喜歡
怎樣寫那都沒有什麼大問題,關鍵是保證不要在標頭檔案中胡亂包含。
    3)、使用基類指標
    這種方法是在引用超前引用類的地方一律用基類指標。而一般情況下,兩個互相引用的類並不涉及其基類,因此不會造成超前引用。比如:在CMyDialog類中用CView*代替CMyView*,在CMyView類中用CDialog*代替CMyDialog*,這樣必然不會造成超前引用。(CMyDialog繼承CDialogCMyView繼承CView)。

http://blog.csdn.net/u010177010/article/details/50816994)

  全域性變數還是會重複定義的。但是對於類而言,定義一個類(屬於型別定義),在類的例項化之前,並沒有產生記憶體的開銷,與基本型別的定義有所區別。

宣告:(可以放在標頭檔案)沒有開闢記憶體的定義,型別定義,比如類的定義,結構體的定義,它是定義一個數據型別而已

定義:(不可放在標頭檔案)開闢了記憶體的定義,資料定義,比如類物件定義,變數定義

一般來說:

   不分配記憶體的,放在標頭檔案
分配記憶體的放在cpp檔案,防止重複定義,當然也要看變數的連線性,內部連線性的可以放在標頭檔案定義。

http://blog.csdn.net/u010177010/article/details/50816994