標籤:c++ effective 編程技術
--------------------1讓自己習慣c++-----------------------------------------
Rule 1 : 把c++看做一個語言聯邦,共有4個次語言:c(區塊、語句、前置處理器、內建資料類型、數組、指標);物件導向c++(類、封裝、繼承、多態、虛函數);模板c++;STL(容器、迭代器、演算法以及函數對象)。當你從某個次語言切換到另一個,導致高效編程規則要求你改變策略時,不要感到驚訝。
Rule 2:盡量以const、enum、inline替換#define,盡量以編譯器代替前置處理器。
Rule 3: 儘可能使用const。const最具微力的應用是面對函式宣告時的應用:函數傳回值,各參數,成員函數自身。
Rule 4:確定對象被使用前已先被初始化。需要關注三方面的問題:1.對內建類型意外的任何其他東西,確保每一個建構函式都將對象每一個成員初始化。2.建構函式的初值列列出的成員變數,其排列次序應該和他們在class中的聲明次序相同。3.定義於不同編譯單元的non-local static對象的初始化次序是不確定的。解決方案:將每個non-local static對象搬到自己的專屬函數內(該對象在此函數內被聲明為static)
-------------------2構造/析構/賦值運算 ----------------------------------------
Rule 5:瞭解c++默默編寫並調用了這些函數(都是public且inline):預設建構函式,預設解構函式,複製建構函式,複製賦值操作符函數。
Rule 6:若不想使用編譯器自動產生的函數,就該明確拒絕。例如若不想類被複製或者賦值,就該明確拒絕,這有兩個方法。
Rule 7:為多態基類聲明virtual解構函式。
Rule 8:讓異常逃離解構函式。解構函式絕對不要吐出異常,這會導致程式可能過早結束或出現不明確的行為。如果一個被解構函式調用的函數可能拋出異常,解構函式應該捕捉任何異常,然後吞下它們(不傳播)或結束程式。
Rule 9:絕不在構造和析構過程中調用虛函數,這類調用從不下降至衍生類別。解決辦法是令衍生類別將必要的構造資訊向上傳遞至base class建構函式。令函數為static,也就不可能意外指向“初期未成熟之對象內尚未初始化的成員變數”。
Rule 10:令operator = 返回一個referenceto *this。
Rule 11:在operator = 中處理“自我賦值”。
Rule 12:複製對象時勿忘其每一個成分。
---------------------3資源管理---------------------------------------------------------
Rule 13:以對象管理資源。令資源在構造期間獲得,在析構期間釋放。
Rule 14:在資源管理類中小心copying行為。當一個RAII對象被複製,會有以下2種處理方式:1.禁止複製,2.對底層資源祭出“引用計數法”:通常只要內含一個tr1:shared_ptr成員變數,RAIIclasses便可實現出引用計數的複製行為。
Rule 15:在資源管理類中提供對原始資源的訪問。
Rule 16:成對使用new和delete時要採用相同的形式。
Rule 17:以獨立語句將newed對象置入智能指標,否則可能導致資源流失,應該將以下語句:
processWidget(std::tr1::shared_prt<Widget>(newWidget),priority());
替換為(獨立語句)
std::tr1::shared_ptr<Widget>pw(new Widget);
processWidget(pw,priority());
----------------------------4設計與聲明-------------------------------------------------------
Rule 18:讓介面容易被正確使用,不易被誤會。
Rule 19:設計class猶如設計type。應該和“語言設計者當初設計語言內建類型時”一樣謹慎地來研討class的設計。
Rule 20:盡量以pass-by-reference-to-const替換pass-by-value,但對內建類型,pass-by-value往往比較適當。
Rule 21:必須返回對象時,別妄想返回其reference。
Rule 22:將成員變數聲明為private。
Rule 23:寧以non-member、non-friend替換member函數。
Rule 24:如果需要為某個函數的所有參數(包括被this指標所指的那個隱喻參數)進行類型轉換,那個這個函數必須是個non-member。
Rule 25:考慮寫出一個不拋出異常的swap函數。
----------------------------------------5實現------------------------------------------------------
Rule 26:儘可能延後變數定義式的出現時間,這樣可以避免構造(和析構)非必要對象。
Rule 27:盡量少做轉型動作。C++的集中轉型類型:
const_cast<T>(expression) //唯一可將對象的常量性移除。
dynamic_cast<T>(expression) //安全向下轉型
reinterpret_case<T>(expression) //執行低級轉型
static_cast<T>(expression) //強迫隱式轉換,例如non-const對象轉為const對象,或將int轉為double等等。
Rule 28:避免返回handles指向對象內部成分,這樣會破壞封裝性和const性。
應該將
Point& upperLeft() const {returnpData->ulhc;}
替換為
const Point& upperLeft() const {returnpData->ulhc;}
Rule 29:為“異常安全”而努力使值得的。
Rule 30:透徹瞭解inlining。一開始不要將任何函式宣告為inline,或至少將inlining施行範圍局限在那些“一定成為inline”或“十分平淡無奇”的函數身上。
Rule 31:將檔案間的編譯依存關係降至最低,將介面與實現分離。一般構想是相依於聲明式,不要相依於定義式。基於此構想的2個手段是handle classes和interface classes。
--------------------------6繼承與物件導向設計---------------------------------
Rule 32:確定你的public繼續塑模出is-a關係。
類之間的三種關係:is-a,has-a,is-implemented-in-terms-of(根據某物實現出)
Rule 33:避免遮掩繼承而來的名稱。
如果你繼承base class並加上重載函數,而你又希望重新定義或覆寫其中一部分,那麼你必須為那些原本會被遮掩的每個名稱引入一個using聲明式,否則某些你希望繼承的名稱會被遮掩。
當你不想繼承base class的所有函數,可以使用private繼承和轉交函數(什麼是轉交函數?調用基類函數的函數)。
Rule 34:區分介面繼承和實現繼承。
Rule 35:考慮virtual函數以外的其他選擇。
藉由non-vitualinterface手法實現template method模式:虛函數應該幾乎總是private,令客戶通過public non-virtual成員函數間接調用private virtual函數。
藉由函數指標實現策略模式。
Rule 36:絕不重新定義繼承而來的non-virtual函數。
Rule 37:絕不重新定義繼承而來的預設(預設)的參數值。
Rule 38:通過複合塑模出has-a或“根據某物實現出”。
Rule 39:明智而審慎地使用private繼承。如果class D以private形式繼承class B,則用意是為了採用classB內已經備妥的某些特性。
Rule 40:明智而審慎地使用多重繼承。
-----------------------7模板與泛型程式設計-------------------------------------------------------------------
Rule 41:瞭解隱式介面和編譯期多態。
classes和templates都支援介面和多態。
對classes而言,介面是顯式的,以函數簽名為中心,多態則通過virtual函數發生於運行期。
對template參數而言,介面是隱式的,奠基於有效運算式(如if語句內的運算式),多態則是通過template具現化和函數重載解析發生於編譯期。
Rule 42:瞭解typename的雙重意義。
Rule 43:學習怎麼獲得基類模板中的名稱。
Rule 44:將與參數無關的代碼抽離templates。
Rule 45:運用成員函數模板接受所有相容類型。
Rule 46:需要類型轉換時請為模板定義非成員函數。
Rule 47:請使用traitsclasses表現類型資訊。
Rule 48:認識templates元編程。
------------------------8定製new和delete------------------------------------------------------------------------
Rule 49:瞭解new-handler的行為。
Rule 50:瞭解new和delete的合理替換時機。
Rule 51:編寫new和delete時需固守常規。
Rule 52:寫了placementnew也要寫placement delete。
------------------------------------9雜項討論----------------------------------------------------------------------------
Rule 53:不要輕忽編譯器的警告。
Rule 54:讓自己熟悉包括tr1在內的標準程式庫。
Rule 55:讓自己熟悉boost。
本文出自 “FireKido的技術人生” 部落格,請務必保留此出處http://zhangzhao.blog.51cto.com/12934593/1970517
effective c++學習筆記