国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

探究多態&虛表

2019-11-08 18:38:39
字體:
來源:轉載
供稿:網友

多態

所謂多態,就是當使用基類的指針或引用調用重寫的虛函數時,當指向父類調用的就是父類的虛函數,指向子類調用的就是子類的虛函數。 下面來通過代碼來理解多態的含義

class AA{public: virtual void fun() { cout << "AA::fun()" << endl; }};class BB : public AA{public: virtual void fun() { cout << "BB::fun()" << endl; }};void FUN(AA& a){ a.fun();}void Test1(){ AA a; BB b; FUN(a); FUN(b);}

結果為: AA::fun() BB::fun() C++的多態分為靜態多態動態多態靜態多態:靜態多態就是重載,因為是在編譯期決議確定。也就是在編譯的時候就能確定函數的地址。 動態多態:是通過繼承重寫基類的虛函數實現的多態,在運行期間決議確定。也就是編譯期間不知道函數的地址,只知道存儲函數地址的虛表的地址。 C++中多態的實現就是通過虛函數實現的,虛函數的對象實例中都存在一張虛函數表。

虛函數表

虛函數表是通過一塊連續內存來存儲虛函數的地址,指明了實際調用的虛函數指針。

class AA{public: virtual void fun1() {} virtual void fun2() {}PRotected: int _a;};void Test2(){ AA a;}

這里寫圖片描述 通過監視窗口可以看到,對象a的首部存儲了一個地址,指向的空間存儲了虛函數的地址,稱為虛函數表。所以sizeof(a)的值為8。

【含有虛函數的單繼承對象模型】

typedef void(*FUNC) ();class AA{public: virtual void fun1() { cout << "AA::fun1()" << endl; } virtual void fun2() { cout << "AA::fun2()" << endl; }protected: int _a;};class BB : public AA{public: virtual void fun1() { cout << "BB::fun1()" << endl; } virtual void fun3() { cout << "BB::fun3()" << endl; }protected: int _b;};void PrintfVTable(int *VTable){ cout << "虛表地址:" << "0x" << VTable << endl; for (int i = 0; VTable[i] != 0; ++i) { cout <<"虛函數地址:0x"<< VTable[i] << " "; FUNC f = (FUNC)VTable[i]; f(); } cout << endl;}void Test3(){ AA a; BB b; int* VTable1 = (int *)(*(int *)&a); int* VTable2 = (int *)(*(int *)&b); PrintfVTable(VTable1); PrintfVTable(VTable2);}

通過這種方式,可以依次打印出虛表地址以及虛函數的地址,結果如下: 這里寫圖片描述 這里寫圖片描述 虛表后面的0標志著虛表結束,類似于字符串結束符“/0”。

提示:若在windows平臺vs下,程序出現異常中斷,可以“清理解決方案”,這是由于編譯器的小bug,沒有在虛表最后加上0,出現死循環。

【含有虛函數的多繼承對象模型】

typedef void(*FUNC) ();class AA1{public: virtual void fun1() { cout << "AA1::fun1()" << endl; } virtual void fun2() { cout << "AA1::fun2()" << endl; }protected: int _a1;};class AA2{public: virtual void fun1() { cout << "AA2::fun1()" << endl; } virtual void fun2() { cout << "AA2::fun2()" << endl; }protected: int _a2;};class BB : public AA1,public AA2{public: virtual void fun1() { cout << "BB::fun1()" << endl; } virtual void fun3() { cout << "BB::fun3()" << endl; }protected: int _b;};void PrintfVTable(int *VTable){ cout << "虛表地址:" << "0x" << VTable << endl; for (int i = 0; VTable[i] != 0; ++i) { cout <<"虛函數地址:0x"<< VTable[i] << " "; FUNC f = (FUNC)VTable[i]; f(); } cout << endl;}void Test4(){ BB b; int* VTable = (int *)(*(int *)&b); PrintfVTable(VTable); VTable = (int *)(*((int*)&b + sizeof (AA1) / 4)); PrintfVTable(VTable);}

這里寫圖片描述 這里寫圖片描述


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 姚安县| 彰化县| 宜兴市| 正镶白旗| 青阳县| 中牟县| 徐汇区| 抚顺县| 张家界市| 通海县| 三明市| 昌乐县| 安岳县| 望谟县| 汝阳县| 绍兴县| 松原市| 长治县| 乌鲁木齐市| 邢台市| 宝兴县| 抚州市| 嘉禾县| 陇南市| 马鞍山市| 田东县| 临沧市| 神池县| 太仓市| 隆尧县| 黄浦区| 塘沽区| 华池县| 石柱| 大悟县| 柘荣县| 郓城县| 曲沃县| 左权县| 云和县| 五指山市|