C++虚表(V-Table)解析

  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 }

 

转载于:https://www.cnblogs.com/jianmoyisheng/p/6406725.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值