1. 程式人生 > >《More Effective C++》讀書筆記(零)Basic 基礎條款

《More Effective C++》讀書筆記(零)Basic 基礎條款

這是篇讀書筆記,只記錄自己的理解和總結,一般情況不對其舉例子具體說明,因為那正是書本身做的事情,我的筆記作為梳理和複習之用,劃重點。我推薦學C++的人都好好讀一遍Effective C++ 系列,真是好書啊,對於學完C++ 基礎知識的人,這是本高階祕籍。值得注意的是 More Effective C++ 是以1997年的C++標準寫的,那時候標準還不完善,20多年過去了,很多語言的漏洞和技術可能被新特性取代了,應該注意最終向新標準看齊。

筆記

  • 條款1:仔細區別pointers 和 reference。 reference 必然指向某個物件,不可以為 null , 不可以改變指向;指著可以為空,可以改變指向。 過載操作符 operator[] 的時候返回reference 更好。int &a =0;\\錯誤!
    , 而int *a = 0 ;\\合法
  • 條款2: 最好使用C++ 轉型操作符。從可讀性和規範來說,不應該使用C語言的轉型了,而應該使用以下四種轉型操作符。
static_cast<T>() const_cast<T>() dynamic_cast<T>() reinterpret_cast<T>()
操作 普通轉型操作 去除某個物件的常量性 繼承體系中安全的向下轉型或者跨系轉型 用來轉換函式指標的型別
注意事項 與C語言舊式轉型有相同威力與意義 只能用於繼承體系中 不具備移植性

dynamic_cast 可以把指向基類的指標或者引用轉換為指向派生類的指標或者引用

  • 條款3:絕對不要以多型的方式處理陣列。 所以如果用基類的陣列存派生類物件,因為基類物件佔用的記憶體和派生類物件佔用記憶體大小不一樣會導致定址出錯。結果不可預期。析構也會出錯,通過base class 的指標刪除derived classes 的物件構成的陣列,結果未定義。多型和指標算術不能混用

    array[i] 表示的是 *(array+i);

  • 條款4:非必要不提供 default constructor。 提供了預設建構函式就是表明構造這個物件不需要額外的引數,表明成員引數都可能被初始化或者類的設計者有責任檢查成員函式是否初始化,帶來額外的負擔。 如果不提供預設建構函式,則在使用物件陣列的時候需要逐個構造,這裡還介紹了一種分配raw memory 和placement new 的技術(可以參見條款8)避免過度使用記憶體; 此外,如果不提供預設建構函式,則不適用許多模板容器類 tamplate-based container class; 還有就是對於虛基類,如果沒有預設建構函式則要求派生類的使用者瞭解構造引數的意義。最終實踐是如果提供預設你建構函式,請記得保證成員有意義

有個三五法則專門講關於構造、解構函式的,準備寫一篇總結,專門講述這方面的。

總結

  1. 區分 reference 引用和pointer 指標;
  2. 最好使用 C++ 的轉型操作符,棄用舊的C 轉型方式;
  3. 多型和指標運算不能混用(陣列索引用了指標算術);
  4. 除非必要,否則不提供預設建構函式。