标题好像有点坑,进来可是干货…
这里找了下 C++下的动态多态的内部实现方法,虚函数表….
讲解未开始,代码先上来…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
#include <iostream> using namespace std; class A { public: virtual void FuncA1() { cout << "A1 Func" << endl; } virtual void FuncA2() { cout << "A2 Func" << endl; } virtual void FuncA3() { cout << "A3 Func" << endl; } virtual void FuncA4() { cout << "A4 Func" << endl; } }; class B { public: virtual void FuncB1() { cout << "B1 Func" << endl; } virtual void FuncB2() { cout << "B2 Func" << endl; } }; class C : public A, public B { public: virtual void FuncA1() { cout << "A1C Func" << endl; } virtual void FuncA2() { cout << "A2C Func" << endl; } virtual void FuncA3() { cout << "A3C Func" << endl; } virtual void FuncB1() { cout << "B1C Func" << endl; } virtual void FuncB2() { cout << "B2C Func" << endl; } }; int main() { C c; cout << "Sizeof A = " << sizeof(A) << endl; cout << "Sizeof B = " << sizeof(B) << endl; cout << "Sizeof C = " << sizeof(C) << endl; typedef void (*Func)(void); void (*pFun)(void) = NULL; cout << endl; pFun = (Func)(&A::FuncA1); cout << "A::FuncA1 : " << (void*)(&A::FuncA1) << " - "; pFun(); pFun = (Func)(&A::FuncA2); cout << "A::FuncA2 : " << (void*)(&A::FuncA2) << " - "; pFun(); pFun = (Func)(&A::FuncA3); cout << "A::FuncA3 : " << (void*)(&A::FuncA3) << " - "; pFun(); pFun = (Func)(&A::FuncA4); cout << "A::FuncA4 : " << (void*)(&A::FuncA4) << " - "; pFun(); pFun = (Func)(&B::FuncB1); cout << "B::FuncB1 : " << (void*)(&B::FuncB1) << " - "; pFun(); pFun = (Func)(&B::FuncB2); cout << "B::FuncB2 : " << (void*)(&B::FuncB2) << " - "; pFun(); pFun = (Func)(&C::FuncA1); cout << "C::FuncA1 : " << (void*)(&C::FuncA1) << " - "; pFun(); pFun = (Func)(&C::FuncA1); cout << "C::FuncA2 : " << (void*)(&C::FuncA2) << " - "; pFun(); pFun = (Func)(&C::FuncA1); cout << "C::FuncA3 : " << (void*)(&C::FuncA3) << " - "; pFun(); pFun = (Func)(&C::FuncB1); cout << "C::FuncB1 : " << (void*)(&C::FuncB1) << " - "; pFun(); pFun = (Func)(&C::FuncB1); cout << "C::FuncB2 : " << (void*)(&C::FuncB2) << " - "; pFun(); cout << endl << endl; cout << "对象c虚函数表-指针:" << (int**)(&c) << endl; cout << "对象c虚函数表1地址:" << (int**)*((int**)&c) << endl; cout << "对象c虚函数表2地址:" << (int**)*((int**)&c + 1) <<endl; cout << endl; cout << "C的第一个虚函数表的第一项的地址 : "; cout << (void*)((int**)*(int**)&c + 0) << endl; pFun = (Func) *((int**)*(int**)&c + 0) ; cout << "C的第一个虚函数表的第一项 : "; pFun(); pFun = (Func)(&C::FuncA1); cout << "C::FuncA1 : " << (void*)(&C::FuncA1) << " - "; pFun(); cout << endl; cout << "C的第一个虚函数表的第二项的地址 : "; cout << (void*)((int**)*(int**)&c + 1) << endl; pFun = (Func) *((int**)*(int**)&c + 1); cout << "C的第一个虚函数表的第二项 : "; pFun(); pFun = (Func)(&C::FuncA2); cout << "C::FuncA2 : " << (void*)(&C::FuncA2) << " - "; pFun(); cout << endl; cout << "C的第一个虚函数表的第三项的地址 : "; cout << (void*)((int**)*(int**)&c + 2) << endl; pFun = (Func) *((int**)*(int**)&c + 2); cout << "C的第一个虚函数表的第三项 : "; pFun(); pFun = (Func)(&C::FuncA3); cout << "C::FuncA3 : " << (void*)(&C::FuncA3) << " - "; pFun(); cout << endl; cout << "C的第一个虚函数表的第四项的地址 : "; cout << (void*)((int**)*(int**)&c + 3) << endl; pFun = (Func) *((int**)*(int**)&c + 3); cout << "C的第一个虚函数表的第四项 : "; pFun(); pFun = (Func)(&C::FuncA4); cout << "C::FuncA4 : " << (void*)(&C::FuncA4) << " - "; pFun(); cout << endl; cout << "C的第二个虚函数表的第一项的地址 : "; cout << (void*)(int**)*((int**)&c + 1) << endl; pFun = (Func) *(int**)*((int**)&c + 1); cout << "C的第二个虚函数表的第一项 : "; pFun(); pFun = (Func)(&C::FuncB1); cout << "C::FuncB1 : " << (void*)(&C::FuncB1) << " - "; pFun(); cout << endl; cout << "C的第二个虚函数表的第二项的地址 : "; cout << (void*) ((int**)*((int**)&c + 1) + 1) << endl; pFun = (Func)* ((int**)*((int**)&c + 1) + 1); cout << "C的第二个虚函数表的第二项 : "; pFun(); pFun = (Func)(&C::FuncB2); cout << "C::FuncB2 : " << (void*)(&C::FuncB2) << " - "; pFun(); } |
一步步讲解代码:
首先我们定义了 A B C 三个类,每个类都有自己的方法,都是虚函数…
然后进入main 函数来看看,首先输出三个类的大小…
可以得到
结论1 :一个类或它的父类定义有虚函数,则有一个指向虚函数表的指针,如果多继承,则有多个指针
接下来,我们找到了函数的地址,然后打印输出了函数地址和他们对应显示的内容。
PS.这种方法是很危险的。
接下来我们找到了对象 c ,输出了它的两个虚函数表的地址。
结论2:虚函数表存放的是函数的地址。
然后呢,输出每个表的表项地址 指向地址(函数) 并 运行函数 得到输出
那如果到这里都理解的话,我们就明白虚函数是咋回事了…
通过指针得到表,表内存地址,查表调用函数…
PS.该代码是不能在VS上运行的,建议用 Dev-CPP…
搞搞虚函数表,无所不用其极…