现在这个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: }