再讀Effective C++

Effective C++ 筆記

10年後再讀Effective C++ 3rd(English),沒有對細節的追問,更多的是對C++設計思路的思考,各章節標題爲是個章節的歸納和總結java

讓本身習慣C++

  • C++由多個部分構成c++

    C, Object-Oriented, Template, STL
  • 儘可能多的使用const,enums,inline代替define面試

    更好的靜態檢查
  • 儘可能多用const編程

    不只是防護式編程,更重要的是再檢驗設計的合理性
  • RAII 資源獲取即初始化安全

    c++編程裏永不過期的一句,不管聲明一個變量或者得到某種資源

默認生成的函數們

  • 留意C++自動生成的代碼:構造,析構,copy構造,operator =函數

    自動生成代碼運行的機制,絕對是筆試,面試中的常客
  • 若是不須要,就顯式的禁用自動生成的代碼this

    各類筆試,面試常常出現只能棧上分配,堆上分配,不能繼承,不能copy等等都是變種
  • 多態基類的析構必須是虛函數設計

    毋庸置疑,C++派生規則中必須遵照的一條,簡單粗暴點就是基類的析構必定是虛函數
  • 析構函數不要拋異常code

    拋了異常就會致使析構傳遞斷裂,資源泄漏在所不免
  • 構造/析構中不要調用虛函數對象

    筆試,面試中常常出現
  • operator = 返回 *this

    鏈式使用不可少
  • 處理好operator = 自賦值

    一樣經典,必不可少
  • 拷貝構造必定要拷貝全

    不要爲何,若是copy少了,必須是copy錯了

資源管理

  • 使用對象管理資源

    3年經驗的必須懂
  • 資源管理類的copy行爲要慎重

  • 資源管理類提供訪問Raw-Resource的方法

    std::string::c_cstr()要明白
  • new/delete 形式要對應

    new <=> delete, new [] <=> delete []
  • 存儲new分配的資源在smart pointer中單獨處理

    void foo(tr1::shared_ptr<Data> obj);
      foo(new data); // wrong
      tr1::shared_ptr<Data> pd (new Data());
      foo(pd); // all right

設計和聲明

  • 接口好用不易錯

    類型轉換處理好
      語意上天然
  • 類設計就是類型設計

    類設計的基本規則之一
  • 常引用傳遞代替值傳遞

    不只減小對象生成消亡的開銷,還能夠簡化代碼
  • 該返回對象時,勿返回引用

    c++不是java,沒有天生的引用計數機制
  • 數據成員私有

    多一層保護多一層自由,要不C#也不會搞屬性,Java搞setter/getter出來
  • 使用非成員,非友元函數替代成員函數

    加強封裝,彈性以及功能擴展,簡單的說,沒必要要的不要放在內部
  • 當參數都須要類型變化時,聲明爲非成員函數

    負數類operator + , 若是能夠接受 int,char,double那麼就聲明爲非成員函數,你們都開心
  • 支持無異常交換

    swap很重要,不管是在拷貝構造仍是賦值運算中

實現

  • 儘可能推遲變量的定義

    首先你要弄清楚什麼是定義,哈哈
  • 最小化CAST

    儘可能不用,尤爲是dynamic_cast,必須用的時候儘可能封裝到函數裏,優先C++ style, no C
  • 避免返回對象的內部處理細節

    對於這樣的代碼情何以堪:
      const Rect r(left, up, right, down);
      rect.getLeftup().setX(x);
      另外,臨時對象也很難hold住
  • 異常安全

    這個怎麼說都不過度
  • 明白inline函數的輸入輸出

    內聯函數短小精悍,二進制升級要考慮好。
  • 最小化文件編譯依賴

    如今的代碼彷佛根本不在意這一套

繼承和麪向對象設計

  • 繼承要符合「is-a」模型

    關鍵在於怎麼理解企鵝是鳥不會飛這樣的無厘頭
  • 避免隱藏繼承來的名字

    這個就是所謂的「隱藏規則」,筆試,面試都會有
  • 區別接口繼承和實現繼承

    virtual的都要設計成接口,非虛的都是實現
  • 考慮虛函數之外的其餘選擇

    解決問題的方法不止一個
  • 毫不從新定義繼承而來的非虛函數

    C++就是這樣,虛與實之間的界限有時清晰有時晦澀
  • 毫不從新定義繼承而來的有默認參數的函數

    c++默認參數靜態綁定
  • 使用組合來表示「A包含B」、「A以B的形式實現」

    弄清楚AB的關係比什麼都重要
  • 明智的使用私有繼承

    私有繼承意味着所有都不能繼續繼承了
  • 明智的使用多繼承

    單繼承多實現是個好主意

模版和範型

  • 理解隱式接口,編譯期多態

    理解接口,理解編譯期多態,理解萬歲
  • 理解typename的兩個含義

    1:和class同樣在模版中,2:表示後面是一個類型
  • 如何訪問模板化基類中的名字

    1:this, 2:using 3:fullname
  • 把與參數無關的代碼抽離templates

    模版生成代碼膨脹要注意
  • 模版函數儘可能多的兼容類型

    多多益善
  • 須要類型轉換時請爲模板定義非成員函數

    放在裏面很彆扭
  • 使用traits classes表現類型信息

    典型的函數式思路和STL實現
  • 瞭解模版元編程

    運行期放到編譯期

自定義new和delete

  • 理解new-handler

    new的內部細節
  • 理解替換new和delete的時機

    沒有特別的理由無需重載
  • 按照約定實現new和delete

    new和delete都有本身的格式
  • 放置new和放置delete

    new和delete必定要對應
相關文章
相關標籤/搜索