類的聲明及定義html
1. class、struct、union保留字均可以用來聲明和定義類。class中成員默認爲private類型,struct、union與C語言兼容,成員默認爲public類型。c++
2. 只有當類沒有顯式的定義構造/析構函數時,C++纔會提供默認的構造/析構函數;默認的構造函數只負責建立對象,不作任何初始化工做。數組
3. 程序正常退出時,析構函數會被隱式調用;非正常退出(如abort)則析構函數不會被調用,可能致使系統資源沒有及時獲得回收。構造函數只能被隱式調用,析構函數能夠被顯式調用。併發
4. 對象在退出其做用域時自動析構,其對象的析構順序與其建立的順序相反;常量對象在建立以後當即析構。函數
類成員的訪問權限測試
1. private說明的對象成員是徹底私有的,即使是派生類的後代對象也不能訪問這類成員。優化
2. protected說明的對象成員是私有的,受保護的,該對象派生的後代能夠訪問這類成員。this
3. public說明的對象成員是徹底公開的,任何對象都能訪問這類成員。spa
4. 不管什麼類型的的對象成員,均可以被友元函數訪問。操作系統
5. 類的訪問權限只能防止無心識的越權訪問,經過強制類型轉換,可對類的成員無限制的進行訪問。
內聯函數
1. 不論是否出現inline保留字,在類體內定義的任何函數成員都會自動成爲內聯函數。
2. 在類題外定義內聯函數,必須用inline顯式的加以說明。
3. 內聯函數的定義必須出如今內聯函數第一次調用以前,不然以普通形式調用(內聯失敗)。
new和delete
1. 對於簡單類型以及沒有定義構造和析構函數的類,malloc/free及new/delete兩種內存分配方式能夠混用;若類定義了構造函數和析構函數,則最好使用new和delete來分配和釋放內存。
2. 在用new爲數組分配空間時,數組的第一維下標能夠是動態的,其它維則要求是靜態的,即必須爲整型常量或常量表達式;若是數組元素的類型爲類,且但願用new建立對象數組,則相應的類必須定義無參數的構造函數,若是沒有定義任何構造函數則使用C++的無參數構造函數。
3. 在全局空間重載new、delete運算符,則全局空間中的使用new、delete將是重載版本。
4. 在類空間重載new、delete運算符,則對於該類的new、delete將使用類的重載版本。
5. delete不須要測試指針是否爲0,由於在delete的實現中已經考慮到了,沒有必要進行重複的測試。
隱含的this指針
1. 類的普通成員函數比靜態成員函數多了一個隱含參數this指針,隱含this指針是普通成員函數的第一個參數,該參數的類型爲指向此類對象的const指針。
2. this能夠用來區別與該函數成員參數同名的數據成員。
3. this能夠用來訪問調用該函數成員的對象、對象的地址和對象的引用。
4. 在非const成員函數中,const的聲明如:C * const this;
在const成員函數中,const的聲明如:const C * const this;
對象初始化
1. 若類定義了構造函數,則其對象必須用類定義的構造函數進行初始化;當類含有隻讀和引用類型的非靜態數據成員時,類必須爲這些成員定義構造函數。
2. 假定數據成員類A包含B類的非靜態數據成員,若是B類定義了帶參數的構造函數,則A類必須定義本身的構造函數,不能使用C++缺省的構造函數。
3. 構造函數必須初始化對象的對象成員,只讀成員和引用成用,且只能在構造函數的函數體前初始化一次;其餘數據成員能夠在構造函數的函數體前初始化,也能夠在構造函數的函數體內再次初始化。
4. 數據成員按其在類中定義的順序初始化,而與他們出如今構造函數體前的順序無關。若是簡單的類型數據成員沒有出如今構造函數的函數體前,則他們的值將被缺省的初始化爲0。
5. 在定義的時候使用A a = A()時,與A a()同樣,只調用構造函數,不調用operator=。
名字空間
1. namespace保留字用於定義名字空間。名字空間必須在程序的全局做用域內定義,不能在函數內定義,最外層名字空間的名稱必須在程序的全局做用域內惟一,名字空間可分屢次定義。沒有名稱的名字空間稱爲匿名名字空間,每一個程序只能有一個匿名名字空間。
2. using保留字用於聲明程序要引用的名字空間成員,或者用於指示程序要引用的名字空間。如using A::x,則將x引入到了代碼所在的做用域,不能再重複定義x;而若是使用using namespace A,則仍可定義x,但須按照A::X才能訪問到A中的x。
3. 名字空間能夠定義別名,以代替過長和難懂的名字空間名稱,如namespace ABCD=A::B::C::D,則之後直接能夠用ABCD來訪問多重名字空間。
const、volatile、mutable
1. 使用const聲明不可變的數據成員,函數成員的參數和返回值等,包含const成員的類必須定義構造函數。
2. volatile修飾的變量表示其可能被併發訪問(修改),該保留字告訴編譯器不要對變量的訪問作任何訪問優化,即不利用寄存器存放中間計算結果,直接訪問對象以便得到對象的最新值。
3. 普通函數成員的參數表後能夠出現const或volatile,其修飾的是函數成員隱含參數this指針指向的對象。
4. mutable修飾的數據成員是易變的,mutable成員總能夠被更新,即便在const類型的成員函數中。
引用
1. 引用時變量的別名,能夠經過別名直接訪問被引用的變量;而指針變量的值是變量的地址,指針是經過地址間接訪問變量的值。
2. 引用必須被初始化,且初始化以後不能再作其餘變量的引用(別名),引用參數則在函數調用時進行初始化。
3. 引用可用於作函數的參數或返回值,避免了傳遞參數時大量數據的拷貝。
4. 在目標代碼中,引用是不存在的,須要使用引用的地方,已經尤爲引用的對象替代了。
引用對象
1. 引用變量是對引用變量的別名,對被引用的變量必須進行構造和析構,而引用變量自己沒有必要構造和析構。
2. 普通引用變量必須用左值初始化,若是用右值表達式進行初始化,就會生成一個臨時的匿名變量,引用參數也同樣;如A &q = new A(3),則在使用完q後必須delete &q,以釋放臨時匿名變量的空間。
3. 非 引用類型的形參是做用域限於函數的局部變量,形參對象的析構是在函數調用返回前完成的,至於形參對象的構造則是在調用時由值參數傳遞的,值參數傳遞將實參 各數據成員的值相應地賦給形參的數據成員,對於指針類型的數據成員則只複製指針的值,而沒有複製指針所指向的存儲單元,即進行淺拷貝。若是類中含有指針成 員,則進行淺拷貝可能致使內存錯誤,必須定義拷貝構造函數,在函數調用時使用拷貝構造函數進行深拷貝。
靜態數據成員
1. 靜態數據成員用於描述類的整體信息,必須在類的體外進行定義並初始化。
2. 靜態數據成員脫離具體對象獨立存在,其存儲單元不是任何對象存儲空間的一部分,但邏輯上所喲對象都共享這一存儲單元,在計算對象或類的存儲空間時不能包含靜態數據成員。
3. 靜態數據成員描述類的整體信息,因爲全局類做用與全部程序文件,故全局類的靜態數據成員也必須做用於全部程序文件,即定義的時候是int P::q = 0,而不是static intP::q = 0,但在類中聲明時要加上static。
4. union的數據成員必須共享存儲空間,而靜態數據成員各自獨立分配存儲單元,故靜態數據成員不能成爲union的成員。
5. 靜態數據/函數成員可經過三種方式訪問:
(1) A::member (2) a.A::member (3) a.member
靜態函數成員
1. 普通成員函數的第一個參數爲隱含this指針,而靜態函數成員沒有隱含的this參數。
2. 構造函數、析構函數、虛函數等有this指針,若函數成員的參數表後出現const、volatile,則該函數成員的參數表必包含隱含的this指針,這些函數不能定義爲靜態函數成員。
3. union不能定義靜態數據成員,但能夠定義靜態函數成員。
從C轉向C++
1. 儘可能用const 和inline 而不用#define
2. 儘可能用而不用
3. 儘可能用new 和delete 而不用malloc 和free
拷貝構造函數調用場合
1. 一個對象以值傳遞的方式傳入函數體
2. 一個對象以值傳遞的方式從函數返回
3. 一個對象須要經過另一個對象進行初始化
函數重載與默認參數
1. C是弱類型的語言,在調用函數時,實參的類型和數目能夠同函數原型不一致;而C++是強類型的語言,調用時實參的個數和類型都必須同函數原型一致。
2. 函數的參數個數或者類型不一樣,則同名的函數被視爲重載函數。
3. 不能同時在函數的原型聲明和函數定義中定義缺省參數(聲明或定義任一位置指定默認參數便可),在調用函數是,非缺省的參數必須傳遞實參,全部缺省的參數必須出如今非缺省參數的右部。
4. 編譯時經過匹配實參和形參來肯定要調用的重載函數,當調用重載函數時,若找不到匹配的函數,或是找到多個匹配的函數(有默認參數的情形),編譯程序均將報錯。
運算符重載
1. 重載不改變運算符的優先級和結合性,通常狀況下,重載也不改變運算符操做數的個數(++/--須要區分前置仍是後置運算符,->改變了操做數的個數)。
2. 除sizeof . * :: 和三目運算符?:外全部的運算符均可以重載;運算符= -> () []只能重載爲類的普通函數成員,不能重載爲靜態函數成員或普通函數。
3. 運算符重載是面向單個類對象的,而不是面向簡單類型或常量的。若是將運算符重載爲普通函數,就必須至少定義一個引用類或者類的參數,且參數不能是對象的指針或者是對象數組類型。
4. 若是重載左值運算符(如+=、=等),則重載後運算符最好返回引用類型,重載爲普通函數的運算符一般爲了方便數據訪問,將其設爲類的友元。
5. 爲了區分單目的前置運算符與後置運算符(++、--),在重載爲後置運算符時,加一個額外的int參數做爲標識。
6. 運算符重載可用於強制類型轉換,如對某個類實現operator int() const {};(const表示強制類型轉換不改變當前對象的值),則當類向int轉換時,該函數會被調用。
靜態綁定與動態綁定
1. 靜態綁定:編譯時綁定,經過對象調用;動態綁定:運行時綁定,經過地址實現。
2. 靜態多態性:函數多態性——函數重載
模板多態性——C++模板(類模板、函數模板)
3. 動態多態性:虛函數(只有用地址才能實現動態多態性)
4. 只有採用「指針->函數()」或「引用變量.函數()」的方式調用C++類中的虛函數纔會執行動態綁定。對於C++中的非虛函數,由於其不具有動態綁定的特徵,因此無論採用什麼樣的方式調用,都不會執行動態綁定。
http://dev.firnow.com/course/3_program/c++/cppxl/2008313/104493.html
5. 執行動態綁定的只有經過地址,即只有經過指針或引用變量才能實現,並且還必須是虛函數。從概念上來講,虛函數機制只有在應用於地址時纔有效,由於地址在編譯階段提供的類型信息不徹底。
模板與繼承
1. 當對象的類型不影響類中函數的行爲時,就要使用模板來生成這樣一組類,如一個支持泛型的堆棧類。
2. 當對象的類型影響類中函數的行爲時,就要使用繼承來獲得這樣一組類,如一個擁有不一樣特性的貓類。
虛函數
1. 重載函數時一種靜態多態函數,其經過靜態綁定完成;虛函數是一種動態多態函數,其經過動態綁定完成。動態綁定的效率很是高,僅比靜態綁定多了一次指針訪問。
2. 虛函數以virtual標示,在基類中定義虛函數,派生類原型相同的函數將自動成爲虛函數,無論進行多少級派生,虛函數的特性將一直保持下去。
3. 虛函數具備隱含的this指針,故虛函數不能定義成靜態成員函數。構造函數擁有隱含的this指針,但構造函數的對象類型必須是肯定的,不須要表現出多態性,故構造函數不能定義爲虛函數。
4. 對於基類和派生類的虛函數,其原型必須徹底相同,但其訪問權限能夠不一樣。
5. 虛函數能夠定義爲inline,也能夠重載,缺省和省略參數。
函數模板
1. 經過保留字template聲明模板,聲明中模板的參數表必須用尖括號括起來,每一個參數必須在函數參數表中至少出現一次,參數表中的參數能夠在實現中並無使用。在套用函數模板生成模板函數時,函數模板參數表的每一個參數都用類型替換。
2. 對於只有一個參數的函數模板,系統能根據參數表自動推到,即調用時能夠省略模板特化參數。
3. 模板能夠將聲明和定義分開,模板中的函數能夠定義缺省參數,也能夠定義爲內聯函數。
4. 編譯程序根據函數模板生成的函數實例成爲模板函數。
5. 根據模板能夠顯式的生成模板函數,如可在調用時生成並調用模板函數。
6. 能夠用特定的類型函數實現覆蓋函數模板。
異常處理
1. 異常是一種意外破壞程序正常處理流程的事件,程序不能經過檢測變量的值偵察異常(這種方式稱爲斷言)。
2. 異常既能夠被硬件引起,又能夠被軟件引起。由硬件引起的異常一般由中斷服務程序產生,如算術運算溢出和除數爲0所產生的異常;由軟件引起的異常一般由throw語句產生,操做系統和應用程序均可能引起異常。
3. 當程序引起一個異常時,在引起點創建一個描述異常的對象並拋出(throw)異常對象,以後控制被轉移(catch)到該異常的處理過程,在引起點建立的對象用於初始化異常處理過程的參數。
4. 位於try中的語句能夠引起多種類型的異常,在try以後能夠定義多種類型的異常處理過程。在定義多個類型的異常處理過程以後,程序之多執行其中一個異常處理過程。在相應的異常處理過程執行完後,緊隨其後的異常處理過程將會被忽略,程序將繼續執行這些異常處理過程以後的語句。
5. 異常處理過程執行完後,還能夠執行沒有操做數的throw語句,繼續傳播該類型的異常,沒有操做數的throw只能在catch中執行(有操做數的throw只能在try中發出),不管有無操做數,throw以後的全部語句都會被忽略,知道遇到參數類型匹配的異常處理過程。
6. 異常處理過程必須定義一個參數,該參數必須是省略參數(以…標示,能匹配任意異常)或是類型肯定的參數。
7. 異常處理按catch塊的順序匹配,基類異常對象能匹配派生類對象,省略參數的catch塊能匹配任意異常;故一般將派生類的catch塊放到基類以前,省略參數的catch塊放到最後。
8. 異常接口聲明的異常有該函數引起,而其自身又不想捕獲和處理的異常,異常接口定義的異常出如今函數參數表的後面,用throw列出要引起的異常類型。如:
void anyexception(); // 可引起任何異常
void noexception() throw(); // 不引起任何異常
void noexpected() throw(A,B); // 引起異常A、B
聲明異常接口時,函數聲明與定義的異常聲明接口要一致,在函數聲明時throw(A),則在函數定義時也許指定throw(A)。
C++標準庫
1. 標準化過程當中,C++生成新頭文件的方法僅僅是將現有C++頭文件名中的 .h 去掉,方法自己不重要,正如最後產生的結果不一致也並不重要同樣。因此變成了,變成了,等等。對於C 頭文件,採用一樣的方法,但在每一個名字前還要添加一個c。因此C 的變成了,變成了,等等。最後一點是,舊的C++頭文件是官方所反對使用的(即,明確列出再也不支持),但舊的C 頭文件則沒有(以保持對C 的兼容性)。實際上,編譯器製造商不會中止對客戶現有軟件提供支持,因此能夠預計,舊的C++頭文件在將來幾年內仍是會被支持。
2. 舊的C++頭文件名如將會繼續被支持,儘管它們不在官方標準中。這些頭文件的內容不在名字空間std 中。
3. 新的C++頭文件如包含的基本功能和對應的舊頭文件相同,但頭文件的內容在名字空間std 中。(在標準化的過程當中,庫中有些部分的細節被修改了,因此舊頭文件和新頭文件中的實體不必定徹底對應。)
4. 標準C 頭文件如繼續被支持。頭文件的內容不在std 中。
5. 具備C 庫功能的新C++頭文件具備如這樣的名字。它們提供的內容和相應的舊C 頭文件相同,只是內容在std 中。