看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《CCWck (幹嘛要暱稱)》之銘言: : 現在原PO想要 只include A的時候 error 有AB的時候正常 : 或許可以考慮改CD的include的方式 : 在A中 include B : 在B中 #ifndef FILE_B : #define FILE_B : #endif : 在CD中 先include B : #ifdef FILE_B : include A : #endif : 如果這樣寫 當你CDE沒有先include B 的話 A也不會被include : 應該就會造成error 你完全沒搞懂原po的目的是什麼 今天 A depends on B,所以 #include A 會自動有 #include B 的效果 在寫 C 或 D 的時候這種情況會造成誤解 一方面是你會以為 A 同時提供了 B 的功能 另一方面這是應該被隱藏的實作細節 在寫 CD 時如果假設 A depends on B,有可能會寫出過份耦合的設計 導致日後 A 更改實作時,連同 CD 也要一起更改 依照你的方法,寫 #include A 之前要先 #ifdef FILE_B 表示寫 CD 的時候要先知道 A depends on B 這項應該被隱藏的資訊 完全和我們的目的相反 更何況日後若 A 更改實作,變成 depends on Z 豈不要把 CD 裡面的 #ifdef FILE_B 改成 #ifdef FILE_Z 正確做法是使用 pimpl A 不再 include B,而是把資訊做如下的包裝: A.h: #ifndef FILE_A #define FILE_A struct A_Impl; // forward declaration class A { public: // member functions for A private: A_Impl* pimpl; }; #endif A.cpp: #include "A.h" #include "B.h" struct A_Impl { B member; }; pimpl 的原理是把 A 用到的成員全部封裝在另一個 struct 中, 並只用 pointer 指向它。 這個 struct 的內容則是寫在 A.cpp 裡面,因此 C 或 D 都看不到。 即使修改過 A 的實作細節,也僅需重編 A.cpp 即可, 不會動到 CD 如果你的 A 在介面上就已經 depends on B,比如說某個函式參數是 B 這種情況表示 A 和 B 無法獨立成兩個模組 你也沒辦法在不動到 CD 的情況下把 A 改成 depends on Z -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 202.39.238.242
hilorrk:pimpl idiom 是正解,但是我覺得更實用的地方是減少 05/26 02:18
hilorrk:compilation time...為了隱藏細節而做的反而少見?(也是因 05/26 02:18
hilorrk:為我的經驗很少,看的 code base 不夠多啦XD 05/26 02:19
legnaleurc:library 或 framework 的介面都會用 pimpl 處理吧 05/26 12:44
suhorng:喔喔!!! 原來如此 (看中文的說明比看英文資料方便太多了阿 05/27 23:18
suhorng:Q_____Q) 這樣就可以隱藏起來了 05/27 23:19
suhorng:謝謝l大 05/27 23:20
cwahbong:還有一種常拿來做比較的是 pure virtual class ,同樣也 05/28 11:02
cwahbong:可以把相依性關在實作裡面 05/28 11:02