標籤:完成 存在 數組 虛函數表 回顧 cout 多態 ioc public
靜態:
(1)類待用資料成員在編譯時間建立並初始化,屬於類,不屬於某個對象,為所有對象所共用,包括該類衍生類別的對象,可以通過類名or對象訪問。
(2)static成員變數,可以實現同類對象間的資訊共用。儲存在資料區段(data-rw){全域變數也是儲存在data區},故而計算類大小時,不將其計算在內。
(3) static成員可以產業能夠為成員函數的選擇性參數{選擇性參數必須放在參數表的最右邊},普通資料成員則不可以。
1 void fun(int a,int b,int c=10);2 fun(1,2); //a=1,b=2,c=103 4 void fun(int a,int b=10,int c);5 fun(1,2); //a=1,b=? c=?
class base{public: static int static_var; int var; void foo1(int i=staitc_var);//正確 void foo2(int i=var);//錯誤}
(4)資料成員的類型和初始化方式:/cite https://www.nowcoder.com/questionTerminal/b73db04e98174120b50b5478839b3f8f?orderByHotValue=1&mutiTagIds=569&page=1&onlyReference=false
| static成員 |
初始化在類外,且不加static修飾 |
| const成員 |
只能在建構函式後的初始化列表中初始化 |
| const static成員 |
類只有唯一一份拷貝,且數值不能改變。因此,可以在類中聲明處初始化,也可以像static在類外初始化 |
(5)靜態成員函數的意義,是在於管理待用資料成員,完成對待用資料成員的封裝。因為非靜態成員函數,在調用時this指標會被當做參數傳入,靜態函數成員屬於類,不屬於對象,無this指標,所以靜態函數成員只能訪問待用資料成員。
(6)靜態成員函數不可以同時聲明為virtual,const,volatile函數。
/cite http://www.jianshu.com/p/a3303c9ba748
/cite http://www.cnblogs.com/Myhsg/archive/2009/07/31/1535650.html
同步IO和非同步IO:
(1)同步IO,發出一個功能調用時,在沒有得到結果之前,該調用就不返回。
(2)非同步IO,當一個非同步呼叫發出後,通過狀態、通知、回呼函數來通知調用者。
IOCP:
(1)IOCP是一個非同步I/O的API,可以高效地將I/O事件通知給應用程式。
C/C++記憶體的申請釋放:
(1)malloc、free無法對非內部類型的對象自動執行建構函式、解構函式。
(2)macllo、free是庫函數,不是運算子,所以不在編譯器控制許可權之內。new、delete不是庫函數,是運算子,所以擁有執行建構函式、解構函式的許可權。
(3)new出來的指標直接帶類型資訊,malloc返回的是void指標。
指標和引用:
(1)指標是一個變數,引用是一個別名。
(2)引用必須在定義的時候初始化,之後不能改變。
(3)引用不可為空,指標可以為空白。
(4)sizeof(指標)為指標本身的大小,sizeof(引用)所指向對象的大小。
(5)不存在多級引用,引用不需要分配記憶體地區。
多態:
通過虛函數,在子類中通過重寫的方式實現多態,實現根據對象的實際類型來調用相應的函數。
(1)存在虛函數的類都有一個一維的虛函數表,類的對象有一個指向虛函數表的虛指標。
(2)抽象類別是至少包括至少一個純虛函數的類。
多態的實現原理:
(1)早期繫結,靜態繫結:編譯器在編譯的時候,需要確定每個對象調用(非虛函數)的地址。
(2)假設存在父類P,父類對指標*pf。子類C,子類對象c。子類和父類具有同名函數say()。當指標pf指向對象c時,通過指標調用say(),會調用父類中的函數。
class P{public: void say() { std::cout<<"I‘m father"; }}class C:public P{ void say() { std::cout<<"I‘m children"; }}void main(){ C c; P *pf=&c; pf->say();}
多態實現機制
理解多態首先要理解類對象的記憶體模型。
子類的對象記憶體模型是:父類的對象所佔記憶體+子類的對象所佔記憶體,所以當建立子類對象的時候,首先回去調用父類的建構函式,構造出父類的對象後,再調用子類的建構函式完成自身的構造。當將子類對象轉換父類對象時,基於安全考慮,編譯器會將該對象認為是子類物件模型的上半部分,也就是父類對象。所以使用類型轉換後的對象指標調用函數的時候,會調用父類對象的函數。這些都是在編譯期間決定的,為了達到對象和函數一一對應的目的,需要使用動態綁定,也就是使用多態。在基類中函數使用virtual關鍵字,此時子類會自動的在其同名函數上也加上,當然也可以手動添加virtual關鍵字。編譯器會給有virtual關鍵字的類建立一個虛函數表(vtable){在建構函式中完成虛表的建立},裡面以一維數組的形式記錄了有virtual關鍵字的函數地址。為了定位vtable,編譯器會給該類的每個對象提供了一個虛函數指標(vptr){在建構函式中完成虛指標的初始化},該指標指向了該對象所屬類的vtable。
在程式運行時,會根據對象的類型初始化虛指標{不使用多態特性時,會根據指標/參考型別來調用相關函數},使其指向正確的vtable。虛表可以繼承,即使子類中沒有重寫虛函數,子類仍然具有該函數的地址,如果子類重寫了該虛函數,那麼新地址會覆蓋繼承下來的虛表中記錄的虛函數原地址,如果子類新增了虛函數,對應的虛函數表中會增加對應項。回顧上文所述的對象記憶體模型,對象會首先執行父類的建構函式,完成父類對象的構造和父類的虛表和虛指標後,再進行自身的構造。
C++整理