讀effective c++的筆記

允許我介紹80-20定律(參見條款M16)。它指出,在一個典型的程序中,80%的運行時間都花在執行20%的代碼上。
條款11(好好閱讀):用delete去刪除一個已經被刪除的指針,其結果是不可預測的。
條款12:儘量使用初始化而不要在構造函數裏賦值。特別是const和引用數據成員只能用初始化,不能被賦值。
條款13:類成員是按照它們在類裏被聲明的順序進行初始化的,和它們在成員初始化列表中列出的順序沒一點關係。
條款14:當通過基類的指針去刪除派生類的對象,而基類又沒有虛析構函數時,結果將是不可確定的。如果聲明虛析構函數爲inline,將會避免調用它們時產生的開銷,但編譯器還是必然會在什麼地方產生一個此函數的拷貝。
條款15:當定義自己的賦值運算符時,必須返回賦值運算符左邊參數的引用,*this。如果不這樣做,就會導致不能連續賦值,或導致調用時的隱式類型轉換不能進行,或兩種情況同時發生。編譯器一般會產生這樣的臨時值(除非顯式地定義了所需要的構造函數——見條款19),但注意臨時值是一個const.
條款16:關於繼承類的拷貝構造函數&賦值運算符函數的寫法。
條款17:在operator=中檢查給自己賦值的情況。
條款19:只有所涉及的構造函數沒有聲明爲explicit的情況下才會這樣,因爲explicit構造函數不能用於隱式轉換。需要訪問非公有成員的非成員函數只能是類的友元函數。
假設f是想正確聲明的函數,c是和它相關的類
.虛函數必須是成員函數。如果f必須是虛函數,就讓它成爲c的成員函數。
.operator>>和operator<<決不能是成員函數。如果f是operator>>或operator<<,讓f成爲非成員函數。如果f還需要訪問c的非公有成員,讓f成爲c的友元函數。
.只有非成員函數對最左邊的參數進行類型轉換。如果f需要對最左邊的參數進行類型轉換,讓f成爲非成員函數。如果f還需要訪問c的非公有成員,讓f成爲c的友元函數。
.其它情況下都聲明爲成員函數。如果以上情況都不是,讓f成爲c的成員函數。


條款26:爲什麼消除“對類成員的引用所產生的二義”時不考慮訪問權限呢?有一個非常好的理由,它可以歸結爲:改變一個類成員的訪問權限不應該改變程序的含義。
條款27:如果不想使用隱式生成的函數(賦值運算符函數、拷貝構造函數)就要顯式地禁止它。
條款29:
string somefamousauthor()           // 隨機選擇一個作家名
{                                   // 並返回之

  switch (rand() % 3) {             // rand()在<stdlib.h>中
                                    // (還有<cstdlib>。參見條款49)
  case 0:
    return "margaret mitchell";     // 此作家曾寫了 "飄",
                                    // 一部絕對經典的作品
  case 1:
    return "stephen king";          // 他的小說使得許多人
                                    // 徹夜不眠
  case 2:
    return "scott meyers";          // 嗯...濫竽充數的一個
  }                               
                                  

  return "";                        // 程序不會執行到這兒,
                                    // 但對於一個有返回值的函數來說,
                                    // 任何執行途徑上都要有返回值
}
const char *pc = somefamousauthor();
1. 產生一個臨時string對象用以保存somefamousauthor的返回值。
2. 通過string的operator const char*成員函數將臨時string對象轉換爲const char*指針,並用這個指針初始化pc。
3. 臨時string對象被銷燬,其析構函數被調用。析構函數中,data指針被刪除(代碼詳見條款11)。然而,data和pc所指的是同一塊內存,所以現在pc指向的是被刪除的內存--------其內容是不可確定的。
因爲pc是被一個指向臨時對象的句柄初始化的,而臨時對象在被創建後又立即被銷燬,所以在pc被使用前句柄已經是非法的了。也就是說,無論想做什麼,當要使用pc時,pc其實已經名存實亡。

條款31:寫一個返回廢棄指針的函數無異於坐等內存泄漏的來臨。
條款35:C++面向對象編程中一條重要的規則是:公有繼承意味着 "是一個"。
條款36:純虛函數最顯著的特徵是:它們必須在繼承了它們的任何具體類中重新聲明,而且它們在抽象類中往往沒有定義。定義純虛函數的目的在於,使派生類僅僅只是繼承函數的接口。
爲一個純虛函數提供定義也是可能的。但調用它的唯一方式是通過類名完整地指明是哪個調用。
條款37:如果寫類D時重新定義了從類B繼承而來的非虛函數mf,D的對象就可能表現出精神分裂症般的異常行爲。也就是說,D的對象在mf被調用時,行爲有可能象B,也有可能象D,決定因素和對象本身沒有一點關係,而是取決於指向它的指針所聲明的類型。
條款41:涉及到"類的行爲" 和 "類所操作的對象的類型"之間的關係時,你必須問自己這樣一個問題:類型T影響類的行爲嗎?如果T不影響行爲,你可以使用模板。如果T影響行爲,你就需要虛函數,從而要使用繼承。
· 當對象的類型不影響類中函數的行爲時,就要使用模板來生成這樣一組類。
· 當對象的類型影響類中函數的行爲時,就要使用繼承來得到這樣一組類。
條款42:如果兩個類之間的繼承關係爲私有,編譯器一般不會將派生類對象(如Student)轉換成基類對象(如Person)。

 

 

 

 


*****在理解指針的時候,應該記住內存並不包含任何與之相關聯的內在的解析。只有通過使用一個特定類型的指針拿一個特殊位置的比特才能解析爲有意義的數據

發佈了25 篇原創文章 · 獲贊 0 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章