Item29 -- 避免傳回內部資料的handles
傳回handle之後,打破了抽象性,所以要避免
對於non-const member functions而言,傳回內部handle也會導致麻煩,當涉及暫時對象,Handle可能變成懸空的(dangling)
Item30 -- 避免寫出member function,傳回一個non-const的指標或引用並指向較低存取層級的members
同條款30,指向底存取層級的members會破壞抽象性,如果非這樣不可,也要加上const進行避免
Item31 -- 千萬不要傳"函數內local對象的引用"或"函數內以new獲得的指標所指的對象"
這次是局部變數可能被析構的問題,主要針對暫時變數
Item32 -- 儘可能延緩變數定義式的出現
需要的時候再定義,延緩定義式的出現,當出錯時就會減少記憶體的使用。
Item33 -- 明智地運用inline
1,好處:直接用代碼替換,減少函數調用成本
2,壞處:造成代碼膨脹現象,可能會導致病態的換頁現象
3,大部分編譯器會拒絕將複雜的(內有迴圈或遞迴調用)函數inline,而所有虛擬函數都不能inline
4,建構函式和解構函式最好不要inline,即使inline,編譯器也會產生出out-of-line副本,以方便擷取函數指標
Item34 -- 將檔案之間的編譯依賴關係降至最低
class Person{ … private:: string name_; Data birthDate_; Address address_; Country citizenship_; } |
為了編譯Person,編譯器必須知道Data/Address/Country等類佔用大小,所以產生了編譯依賴,使用make的時候,當任何一個內部類變化,使用Person的代碼都會編譯。如果客戶只需要使用Person的公開介面,底層實現是由別人提供的,那麼客戶是不願意每次在底層代碼更新之後都要對自己的代碼重新編譯。
解決方案是使用指標,又稱handle class
class string; class Address; class Country; class PersonImpl; class Person{ public: … string name() const; string birthDate() const; string address() const; string nationality() const; private: PersonImpl * impl } |
或者定義介面,讓Person成為特殊的抽象類別,成為Protocol class,採用Factory 方法,產生能夠有具體實現的對象,類似於單鍵模式。