c++在介面和實現之間的分離這部分工作做的不好。像下面這樣的類定義,不僅指明了介面,也包含了一部分的實現細節。這將導致對實現的依賴。實現一旦改變,將增加整個的編譯時間。
class person ;
要想編譯person,就必須要知道string、date和address的定義。這些定義都是通過下面那樣的include來提供的:
#include #include "date.h" #include "address.h"
可是,這樣的include建立了person對這些標頭檔案的編譯依賴。如果這三個標頭檔案改變,person就要重新編譯(string是標準庫,改變的機率不大,可以隨便包含)。當然依賴person的也要重編,於是產生了級聯效應。
解決這個問題有兩個辦法:把person變成控制代碼類(handle class)或介面類(inte***ce class)。
先看控制代碼類:
#include // standard library components shouldn't be forward-declared #include // for tr1::shared_ptr class personimpl; // forward decl of person impl. class class date; // forward decls of classes used in class address; // person inte***ce class person ; // std::tr1::shared_ptr
可以看到,這個標頭檔案不再依賴date和address的標頭檔案了,所以可以放心地把person給客戶使用。
因為這個person只是乙個宣告(而非定義),隱藏了實現細節,所以使用者不會寫出依賴內部實現的**;當person的實現改變時,使用的客戶也不會再受波及。
這種方案的特徵:兩個標頭檔案!
比如上面的person類,就會有personfwd.h和personimpl.h兩個。給客戶用的只有personfwd.h。
再看介面類:
class person ;
使用介面類,一般會在介面類裡定義工廠函式(factory function),或叫作虛擬建構函式(virtual ctor),然後再從person裡派生出實體類(concrete class)。
使用介面類和控制代碼類的代價:執行時的速度會慢一點;記憶體會多一點。
控制代碼類:因為使用了impl指標,所以多了一點記憶體。這個指標要初始化,要為物件申請記憶體,要銷毀。
介面類:有虛函式指標,要進行函式跳轉。
無論是控制代碼類,還是介面類,都不能使用inline函式。以person為例,personfwd.h裡是不能出現任何函式體的。
但是因為這一點點代價就不使用控制代碼類和介面類了嗎?答案是否定的。因為要盡量減小對客戶的影響。
Linux編譯時如何減小so庫檔案的大小
今天問了我這個問題,我就順便記錄一下。客戶問為什麼libc.so檔案再編譯前和編譯後的size不一樣啊,staging 和 compile 兩個dir下的 libc.so大小不一樣,具體有什麼區別嗎?這是是因為編譯的時候還會用strip工具來處理庫檔案,把二進位制檔案中的包含的符號表和除錯資訊刪除掉...
減小VC6編譯生成的exe檔案的大小的方法
1 減小vc6編譯生成的exe檔案的大小,最有效的方法就是 步驟 1.使用release版本 2.中增加 pragma comment linker,opt nowin98 3.project setting c c link 勾上ignore all default libraries 4.pro...
降低檔案之間的編譯依賴性
當乙個類裡面有別的檔案中定義的型別的成員物件的時候,這兩個檔案一般來說,就有了依賴性。例如 widgeta.h class widgeta class widgetb 使用widgetb的時候我們需要包含widgeta.h標頭檔案,否則編譯器會告訴你找不到定義,所以我們一般會在widgetb.h的頭...