C++中的虛函數的作用主要是實現了多態,本人通過代碼驗證的方式了解虛表的結構及在多種繼承方式下通過虛表訪問子類函數。驗證結果如下:
1)無虛函數覆蓋的一般繼承:可以通過子類的虛表訪問父類的函數
2)虛函數重載父類的虛表:子類重載的虛函數會覆蓋父類的函數
3)多重繼承無重載的虛表:多重繼承子類的虛表就像一張二維表,可以像遍歷二維數組一樣訪問所有父類函數
4)多重繼承有重載的虛表:所有父類被重載的虛函數都會被覆蓋
5)父類指針訪問子類自己的虛函數
6)公有繼承訪問父類非公有虛函數
1 #include "stdafx.h" 2 #include <iostream> 3 #include <Windows.h> 4 using namespace std; 5 // 基類 6 class Base 7 { 8 public: 9 virtual void Fun1() 10 { 11 cout << "Base::Fun1" << endl; 12 } 13 virtual void Fun2() 14 { 15 cout << "Base::Fun2" << endl; 16 } 17 virtual void Fun3() 18 { 19 cout << "Base::Fun3" << endl; 20 } 21 22 private: 23 24 }; 25 26 // 無重載繼承類 27 class Derive :Base 28 { 29 public: 30 virtual void DeriveFun1() 31 { 32 cout << "Derive::Fun1" << endl; 33 } 34 virtual void DeriveFun2() 35 { 36 cout << "Derive::Fun2" << endl; 37 } 38 virtual void DeriveFun3() 39 { 40 cout << "Derive::Fun3" << endl; 41 } 42 }; 43 44 // 重載繼承類 45 class Override :public Base 46 { 47 public: 48 virtual void Fun1() 49 { 50 cout << "Override::Fun1" << endl; 51 } 52 virtual void OverrideFun2() 53 { 54 cout << "Override::Fun2" << endl; 55 } 56 virtual void OverrideFun3() 57 { 58 cout << "Override::Fun3" << endl; 59 } 60 }; 61 62 // 多重繼承無重載 63 class Base1 64 { 65 public : 66 virtual void Fun1() 67 { 68 cout << "Base1::Fun1" << endl; 69 } 70 virtual void Fun2() 71 { 72 cout << "Base1::Fun2" << endl; 73 } 74 virtual void Fun3() 75 { 76 cout << "Base1::Fun3" << endl; 77 } 78 }; 79 class Base2 80 { 81 public: 82 virtual void Fun1() 83 { 84 cout << "Base2::Fun1" << endl; 85 } 86 virtual void Fun2() 87 { 88 cout << "Base2::Fun2" << endl; 89 } 90 virtual void Fun3() 91 { 92 cout << "Base2::Fun3" << endl; 93 } 94 }; 95 class MultipleDerive :public Base, public Base1, public Base2 96 { 97 public: 98 virtual void MultipleDeriveFun1() 99 { 100 cout << "MultipleDerive::Fun1" << endl; 101 } 102 virtual void MultipleDeriveFun2() 103 { 104 cout << "MultipleDerive::Fun2" << endl; 105 } 106 virtual void MultipleDeriveFun3() 107 { 108 cout << "MultipleDerive::Fun3" << endl; 109 } 110 }; 111 // 多重繼承重載 112 class MultipleDeriveOverride :public Base, public Base1, public Base2 113 { 114 public: 115 virtual void Fun1() 116 { 117 cout << "MultipleDerive::Fun1" << endl; 118 } 119 virtual void MultipleDeriveFun2() 120 { 121 cout << "MultipleDerive::Fun2" << endl; 122 } 123 virtual void MultipleDeriveFun3() 124 { 125 cout << "MultipleDerive::Fun3" << endl; 126 } 127 }; 128 // 公有繼承訪問父類非公有虛函數 129 class Base3 130 { 131 private: 132 virtual void Fun1() 133 { 134 cout << "Base3::Fun1" << endl; 135 } 136 137 }; 138 139 class Derive1 : public Base3 140 { 141 142 }; 143 typedef void(*Fun)(void); 144 // 驗證虛函數表 145 void Sub_1(); 146 // 驗證無虛函數覆蓋的一般繼承 147 void Sub_2(); 148 // 驗證虛函數重載父類的虛表 149 void Sub_3(); 150 // 驗證多重繼承無重載的虛表 151 void Sub_4(); 152 // 驗證多重繼承有重載的虛表 153 void Sub_5(); 154 // 驗證父類指針訪問子類自己的虛函數?? 155 void Sub_6(); 156 // 驗證公有繼承訪問父類非公有虛函數 157 void Sub_7(); 158 159 int main() 160 { 161 //Sub_1(); 162 //Sub_2(); 163 //Sub_3(); 164 //Sub_4(); 165 //Sub_5(); 166 //Sub_6(); 167 Sub_7(); 168 return 0; 169 } 170 void Sub_7() 171 { 172 Derive1 v1; 173 Fun pFun = (Fun)*((int*)*(int*)(&v1) + 0); 174 pFun(); 175 } 176 void Sub_6() 177 { 178 Base *v1 = new Override(); 179 // 多態 180 v1->Fun1(); 181 Fun pFun = NULL; 182 //pFun = (Fun)*((Override*)(v1)); 183 pFun(); 184 } 185 void Sub_5() 186 { 187 MultipleDeriveOverride v1; 188 Fun pFun = NULL; 189 Base *b = &v1; 190 Base1 *b1 = &v1; 191 Base2 *b2 = &v1; 192 b->Fun1(); 193 b->Fun2(); 194 b->Fun3(); 195 b1->Fun1(); 196 b1->Fun2(); 197 b1->Fun3(); 198 b2->Fun1(); 199 b2->Fun2(); 200 b2->Fun3(); 201 } 202 void Sub_4() 203 { 204 MultipleDerive v1; 205 Fun pFun = NULL; 206 int** pVtable = (int**)&v1; 207 // Base的第一函數 208 pFun = (Fun)pVtable[0][0]; 209 pFun(); 210 // Base的第二函數 211 pFun = (Fun)pVtable[0][1]; 212 pFun(); 213 // Base的第三函數 214 pFun = (Fun)pVtable[0][2]; 215 pFun(); 216 // 繼承類的第一函數 217 pFun = (Fun)pVtable[0][3]; 218 pFun(); 219 // 繼承類的第二函數 220 pFun = (Fun)pVtable[0][4]; 221 pFun(); 222 // 繼承類的第三函數 223 pFun = (Fun)pVtable[0][5]; 224 pFun(); 225 // Base1的第一函數 226 pFun = (Fun)pVtable[1][0]; 227 pFun(); 228 // Base1的第二函數 229 pFun = (Fun)pVtable[1][1]; 230 pFun(); 231 // Base1的第三函數 232 pFun = (Fun)pVtable[1][2]; 233 pFun(); 234 // Base2的第一函數 235 pFun = (Fun)pVtable[2][0]; 236 pFun(); 237 // Base2的第二函數 238 pFun = (Fun)pVtable[2][1]; 239 pFun(); 240 // Base2的第三函數 241 pFun = (Fun)pVtable[2][2]; 242 pFun(); 243 } 244 void Sub_3() 245 { 246 Override v1; 247 Fun pFun = NULL; 248 // 運行重載第一函數 249 pFun = (Fun)*((int*)*(int*)(&v1)); 250 pFun(); 251 // 運行父類第二函數 252 pFun = (Fun)*((int*)*(int*)(&v1)+1); 253 pFun(); 254 // 運行父類第三函數 255 pFun = (Fun)*((int*)*(int*)(&v1)+2); 256 pFun(); 257 // 運行重載第二函數 258 pFun = (Fun)*((int*)*(int*)(&v1) + 3); 259 pFun(); 260 // 運行重載第三函數 261 pFun = (Fun)*((int*)*(int*)(&v1) + 4); 262 pFun(); 263 } 264 void Sub_2() 265 { 266 Derive v1; 267 Fun pFun = NULL; 268 // 運行父類第一函數 269 pFun = (Fun)*((int*)*(int*)(&v1)); 270 pFun(); 271 // 運行父類第二函數 272 pFun = (Fun)*((int*)*(int*)(&v1) + 1); 273 pFun(); 274 // 運行父類第三函數 275 pFun = (Fun)*((int*)*(int*)(&v1) + 2); 276 pFun(); 277 // 運行子類第一函數 278 pFun = (Fun)*((int*)*(int*)(&v1) + 3); 279 pFun(); 280 // 運行子類第二函數 281 pFun = (Fun)*((int*)*(int*)(&v1) + 4); 282 pFun(); 283 // 運行子類第三函數 284 pFun = (Fun)*((int*)*(int*)(&v1) + 5); 285 pFun(); 286 } 287 void Sub_1() 288 { 289 Base v1; 290 Fun pFun = NULL; 291 cout << "虛函數表地址:" << (int*)(&v1) << endl; 292 cout << "虛函數表第一函數地址:" << (int*)*(int*)(&v1) << endl; 293 // 運行第一個函數 294 pFun = (Fun)*((int*)*(int*)(&v1)); 295 pFun(); 296 // 運行第二個函數 297 pFun = (Fun)*((int*)*(int*)(&v1) + 1); 298 pFun(); 299 // 運行第三個函數 300 pFun = (Fun)*((int*)*(int*)(&v1) + 2); 301 pFun(); 302 // 虛函數表的結束 303 cout << ((&v1) + 3) << endl; 304 }
