**:
前向宣告概念(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...