c 標頭檔案包含問題 include class

2021-07-10 15:59:31 字數 2625 閱讀 8662

**:

前向宣告概念(forward declaration)

在程式中引入了類型別的b.在宣告之後,定義之前,類b是乙個不完全型別(incompete type),即已知b是乙個型別,但不知道包含哪些成員.不完全型別只能以有限方式使用,不能定義該型別的物件,不完全型別只能用於定義指向該型別的指標及引用,或者用於宣告(而不是定義)使用該型別作為形參型別或返回型別的函式.

前向宣告應用場景

當你需要定義兩個類或者結構,例如a和b,而這兩個類需要互相引用,這時候在定義a的時候,b還沒有定義,那怎麼引用它呢,這時候就需要前向宣告(forward declaration)了,前向宣告格式如下: class b;當你在定義類a之前宣告了b,那麼就會在程式中引入了類型別的b,編譯器知道你會在後面的某個地方定義類b,所以允許你在類a中引用類b。但是,在宣告之後,定義之前,類b是乙個不完全型別(incompete type),即已知b是乙個型別,但不知道這個型別的一些性質(比如包含哪些成員和操作)。

前向宣告的使用限制:(就拿上面宣告b類說明)

1.不恩能夠定義b類的物件;

2.可以用於定義只想這個型別的指標或者引用;

3.用於宣告使用該型別作為形參或者返回型別的函式;

除了上面的限制,我們可以用它做些什麼事情嗎?

在c++中,如果要編寫乙個新類的標頭檔案,一般是要#include一堆依賴的標頭檔案,但利用前向宣告和c++編譯器的特性,可以減少這裡的工作量。

因為c++編譯器做的事情主要是:1.掃瞄符號;2.確定物件大小。利用這個特性,當我們編寫乙個新類的標頭檔案時,就可以用前向宣告,減少大量的#include,減少編譯的

工作量。

例如:1.b類用到a類,操作如下,就不需要加a.h了,減少編譯工作量

1:2:

3:class a;//呼叫類a,前向宣告

4:class

5: b

6: ;

2.在宣告成員函式的形參或者返回型別時,也可以用前向宣告

即使我們沒有定義乙個foo類,也可以用,因為成員函式不佔類物件的大小,編譯器可以確定物件大小,前向宣告的作用在於告訴編譯器這個乙個在別的地方定義的型別。這樣編譯器就能生成正確的符號表了。

1:2:

3:class foo;

4:class

5: sample

6: ;

在一些大的工程中,可能會包含幾十個基礎類,免不了之間會互相引用(不滿足繼承關係,而是組合關係)。也就是需要互相宣告。好了,這時候會帶來一些混亂。如果處理得不好,會搞得一團糟,根據我的經驗,簡單談談自已的處理辦法:

編碼時,我們一般會盡量避免include標頭檔案,而是採用宣告class ***。 但有時候還是必須用include標頭檔案,那麼,兩者的劃分在於什麼呢?

應該是很明確的,但書上好像都少有提及。

首先:我們要明白為什麼要用宣告取代標頭檔案包含:對了,是為了避免無必要的重編譯(在標頭檔案發生變更時)。 工程較大,低速機,或基礎類經常變更(不合理的設計吧),編譯速度還是會在意的, 另外,更為重要的是,採用宣告可降低**(class)之間的藕合度,這也是物件導向設計的一大原則。

二:一般原則:

a.標頭檔案中盡量少include,如果可以簡單申明class clsold;解決,那最好。減少沒有必要的include;

b.實現檔案中也要盡量少include,不要include沒有用到的標頭檔案。

三:那什麼時候可以只是簡單宣告class clsold呢?

簡單的說:不需要知道clsold的記憶體布局的用法都可以(靜態成員除外),也就是講如果是指標或引用方式的 都行。

比如:clsold * m_pold; //指標佔4個位元組長

clsold & test(clsold * pold) ;

一切ok。

四:什麼時候不能簡單宣告class clsold,必須include呢?

不滿足三的情況下:

比如:clsold m_objold; //不知道佔據大小,必須要通過它的具體宣告來計算

原因很簡單,想想你要計算sizeof(classnew),但連clsold的size都不知道,編譯器顯然會無能為力。

特殊情況:

int test()

靜態成員呼叫,想來應該是不需要知道記憶體布局的,但因為需要知道m_sint是屬於clsold命名空間 的,如果只宣告class ***顯然是不足以說明的,所以必須包含標頭檔案。

綜上所述,我有以下幾點建議:

1:如果有共同相關依賴(必須include)的類,比如a,b都依賴d可以放在一起,然後直接include "d"類的使用者只需關心與本類暴露出的相關型別,內部用到的型別不用去管(不用自已去include d)。這樣 給出的class,呼叫者才更好用(不用去看**查詢,是不是還需要包含其它標頭檔案)。

2:如果a類依賴d b類不依賴d,可以把它們分開兩個標頭檔案。各自include。這樣可避免當d發生變化時, 避免不必要重編譯。

3:類中盡量採用指標或引用方式呼叫其它類,這樣就可以只宣告class ***了。並且這也符合資源最優 利用,更利於使用多型。

include包含C 的所有標頭檔案

參考部落格 使用和平常的標頭檔案一樣,如下 includeusing namespace std int main int a,b cin a b cout 這個標頭檔案包含以下等等c 中包含的所有標頭檔案 include include include include include includ...

include包含C 的所有標頭檔案

使用和平常的標頭檔案一樣,如下 includeusing namespace std int main int a,b cin a b cout 這個標頭檔案包含以下等等c 中包含的所有標頭檔案 include include include include include include incl...

include包含C 的所有標頭檔案

使用和平常的標頭檔案一樣,如下 include using namespace std int main include這個標頭檔案包含以下等等c 中包含的所有標頭檔案 include include include include include include include include i...