《Effective C++》重點摘要(五)

《Effective C++》第五章:實現

  1. 儘可能延後變量定義式的出現時間。只有變量在恰好要使用之前定義,程序的可讀性往往會得到提高,因爲這樣不容易忘記變量說代表的意思。另一方面,這樣做可以提高程序性能,如果不需要一個變量時卻要爲它分配、釋放空間,調用構造、析構函數,獲取、釋放資源……這,真是太浪費了。補充一點,聲明式並不會做這些事情,所以可以考慮用聲明式替換定義式以儘量延後變量的定義。
  2. 儘量少做轉型動作。轉型意味着出錯的可能性大大提升,轉型意味着更多的操作。如果不得不轉型,考慮使用C++ style的形式,或提供一個專門的轉型函數。
  3. 避免返回handles指向對象內部成分。引用、指針、迭代器都是指向對象內部成分的handles,返回這些東西就把他們的生殺大權交給了別人,降低了封裝性,安全性。如果不得不使用對象內部的成分,考慮返回const型,只讓外部具有讀取的權利。
  4. 爲”異常安全“而努力是值得的。“異常安全”的代碼不泄露任何資源,不允許數據敗壞。“異常安全”的代碼提供三個保證之一:(1)基本承諾。出現異常時,程序內的任何事物仍然處在有效狀態下。沒有任何對象或數據結構因此而敗壞。(2)強烈保證。操作要麼成功,要麼不成功。如果操作失敗,程序回到操作前的狀態。(3)不拋擲保證。不拋出異常。實際情況下,函數內部調用的函數未必提供相應的保證,所以不能總是控制函數具有“異常安全”性,所以,如果全在你的掌控之中,請提供一種異常保證,如果不能,請在文檔裏說明。
  5. 透徹瞭解inlining的裏裏外外。Inline函數很好,但是過度的inline函數會增加程序的目標碼。因爲編譯器對於inline函數的處理是:對於每個inline函數的調用,都以函數的本體替換之,而不是保存現場,跳轉到函數的入口處。Inline函數實現放在頭文件裏的原因是編譯器在編譯時就要知道inline函數是什麼樣子的,以便完成替換。另外一個重點是inline是對編譯器的一項建議,是否真正inline由編譯器決定。如果要寫inline函數,針對那些頻繁調用的簡單函數。
  6. 將文件間的編譯依存關係降至最低。如果只是修改了程序的一部分,卻要重新編譯許多不相關的模塊,這真是令人焦躁而無語。這主要是由於C++的編譯規則引起的,如果A文件裏include了B文件,現在只是對A進行修改,那麼重新編譯時B文件也會被重新編譯,而B文件又include了C、D、E文件,而C、D、E文件又……這看起來就是個災難,所以,非常有必要將文件間的編譯依存關係降至最低。至少有三種方式可以做出這樣的努力:
    1) 能使用object reference 或 object pointer,就不要使用object。reference 或 pointer只需要一個聲明式就可以了,不需要定義式。
    2) 如果能夠,儘量以class聲明式替換class定義式。
    3) 爲聲明式和定義式提供不同的頭文件,像std那樣組織起自己的類。
    pimpl idiom手法和abstract base class可以幫助實現上面的方式,並且abstract base class往往意味着多態,而這正是面向對象的思想的體現。23中經典模式裏多態還少嗎?
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章