探秘C++机制的实现
作者:网络转载 发布时间:[ 2013/4/11 10:19:27 ] 推荐标签:
现在这个Child对象较前面的多了四个字节。内存布局(从低地址到高地址)是:虚表指针__vfptr,iA_,iB_,iC_。
好。问题来了,Child继承了Father,但是Father的函数并没有为Child再量身定做一次,也是说无论是Father对象还是Child对象,他们调用FuncA()都是同一个函数。但是Father并没有__vfptr,Child对象在头部多了这个,FuncA()中用this指针定位iA_和iB_不是都不正确吗?
现象告诉我们FuncA()是可以正确访问iA_和iB_,所以推测Child对象在调用FuncA的时候,传的不是真正的首部地址,而是往后偏移了四个字节。
反汇编,确实如此。这么说Father类里不能调用虚函数了?当然,Father都还不知道虚函数这回事,怎么在FuncA中调用。
还有一个有趣的现象:
1: #include <stdio.h>
2:
3: class Base
4: {
5: public:
6: virtual void ShowID()
7: {
8: printf("Base
");
9: }
10: };
11:
12: class CB : public Base
13: {
14: public:
15: virtual void ShowID()
16: {
17: printf("CB
");
18: }
19: };
20:
21: class CC : public Base
22: {
23: public:
24: virtual void ShowID()
25: {
26: printf("CC
");
27: }
28: };
29:
30: void Test( CB& oB )
31: {
32: oB.ShowID();
33: }
34:
35: int main()
36: {
37: Base oBase;
38: CB oB;
39: CC oC;
40:
41: CB* pCB = &oB;
42:
43: *(int*)(&oB) = *(int*)(&oC); //修改虚表指针
44: oB.ShowID();
45: ((CB*)(&oB))->ShowID();
46: pCB->ShowID();
47: Test(oB);
48:
49: return 0;
50: }

sales@spasvo.com