多继承情况下,虚表指针的一个有关问题

多继承情况下,虚表指针的一个问题
我知道:
1. 有虚函数的类都有一个一维的虚函数表叫虚表,虚表里存放着虚函数的地址
2. 有虚函数的类对象保存着一个指向虚表的指针
3. 父类和子类共享虚表指针
4. 多重继承增加额外的指针
5. 就算一个class有再多的虚函数,sizeof()大小也不会变
6. 一个class再多加一个父类,会多增加一个虚表指针
7. 我知道VC2005/2010支持编译选项/d1reportAllClassLayout ,可以dump出来所有的类的内存模型。
8. 我知道"占地方的不是函数指针,是虚函数表指针"

我也知道:
假设 Derived 除了 Base外,还继承 Base2,并且 Base2 中有两个虚函数 x() 和 y (),那么 Derived 对象的存储结构也许是这样的(只是大概,和具体编译器相关)。

Derived: VTable_D:
----------- --------------
| vptr | | f() 入口 |
+---------+ +----------+
| Base的 | | g() 入口 |
| 数据 | -------------
+---------+
| vptr2 | VTable_D2:
+---------+ -------------
| Base2的 | | x() 入口 | 
| 数据 | +-----------+
+---------+ | y() 入口 |
| Derived的| -------------
| 数据 |
------------
**************************************************************
问题是:
多重继承的条件下,一个 vptr 行不行呢? 我没有看出来“所以这些虚函数入口是不能放在同一个虚表当中的”怎么就不行了。f,g和x,y并不同名啊。放在一个表里面,用一个vptr去指,会有什么问题么?

我写了一段测试程序。测试程序可以得到s1,s2,s3的虚表的地址,但是对于s4和s5,只能得到第一个虚表的位置,而得不到第二个虚表的位置。这是为什么呢?下面这段测试代码,运行结果如下:
4,4,4,8,8

s1 vtble address=00416964
s2 vtble address=00416954
s3 vtble address=004169A4
s4 vtble address1=00416A94
s4 vtble address2=CCCCCCCC //是不是应该指向s4::s2的虚表,不应该是CCCCCCCC
s5 vtble address1=004169B0
s5 vtble address2=CCCCCCCC //是不是应该指向s5::s2的虚表,不应该是CCCCCCCC

求高手解释!!!@!!
源代码如下:
**************************************************************
C/C++ code

#include "stdafx.h" 
#include <string> 
using namespace std; 
struct s1{ 
    virtual void f(){}; 
}o1; 
struct s2{ 
    virtual void g(){}; 
}o2; 
struct s3: public s1{ 
    virtual void x(){}; 
}o3; 
struct s4: public s1,s2{
}o4; 
struct s5: public s1,s2{
    virtual void y(){}; 
}o5; 
int  main( void){ 
     printf("%d,%d,%d,%d,%d\n\n",sizeof(s1),sizeof(s2),sizeof(s3),sizeof(s4),sizeof(s5));
     typedef void(*virtual_function)(void);
     struct s123_equivalence{
         virtual_function* pVtbl;
     }o123;
     memcpy(&o123,&o1,sizeof(s3));
     printf("s1 vtble address=%p\n",o123.pVtbl);
     memcpy(&o123,&o2,sizeof(s3));
     printf("s2 vtble address=%p\n",o123.pVtbl);
     memcpy(&o123,&o3,sizeof(s3));
     printf("s3 vtble address=%p\n",o123.pVtbl);

     struct s45_equivalence{
         virtual_function* pV1;
         virtual_function* pV2;
     }o45;
     memcpy(&o45,&o4,sizeof(s3));
     printf("s4 vtble address1=%p\n",o45.pV1);
     printf("s4 vtble address2=%p\n",o45.pV2);

     memcpy(&o45,&o5,sizeof(s3));
     printf("s5 vtble address1=%p\n",o45.pV1);
     printf("s5 vtble address2=%p\n",o45.pV2);

     return 0; 
} 




------解决方案--------------------
多重继承的条件下,一个 vptr 行不行呢? 我没有看出来“所以这些虚函数入口是不能放在同一个虚表当中的”怎么就不行了。f,g和x,y并不同名啊。放在一个表里面,用一个vptr去指,会有什么问题么?
你怎么维护子对象的完整性呢?
------解决方案--------------------
我知道:
1. 有虚函数的类都有一个一维的虚函数表叫虚表,虚表里存放着虚函数的地址
2. 有虚函数的类对象保存着一个指向虚表的指针
3. 父类和子类共享虚表指针
4. 多重继承增加额外的指针
5. 就算一个class有再多的虚函数,sizeof()大小也不会变
6. 一个class再多加一个父类,会多增加一个虚表指针
7. 我知道VC2005/2010支持编译选项/d1reportAllClassLayout ,可以dump出来所有的类的内存模型。
8. 我知道"占地方的不是函数指针,是虚函数表指针"
---------------------------------
这是你所理解的?
3,4,6是有问题的
何为共享虚表指针?虚表是和类相关的,派生类的虚表是派生类的,基类的是基类的
为什么要增加额外的指针呢?除了虚继承会增加额外的指针外,虚表指针是永远只有一个的而不管基类有多少个
同上,和基类个数没有关系。

------解决方案--------------------
探讨

你怎么维护子对象的完整性呢?

------解决方案--------------------
N个父类就有N虚表指针。
不共享虚表

4lshuodfdfd
------解决方案--------------------
代码写的有点小问题! 已经修改如下,这样应该就是你想要的结果吧!另外查看变量地址不需要这么复杂,直接调试看多方便!效果如图:
C/C++ code
#include "stdafx.h" 
#include <string> 
using namespace std; 
struct s1{ 
    virtual void f(){}; 
}o1; 
struct s2{ 
    virtual void g(){}; 
}o2; 
struct s3: public s1{ 
    virtual void x(){}; 
}o3; 
struct s4: public s1,s2{
}o4; 
struct s5: public s1,s2{
    virtual void y(){}; 
}o5; 


int  main( void){ 
     printf("%d,%d,%d,%d,%d\n\n",sizeof(s1),sizeof(s2),sizeof(s3),sizeof(s4),sizeof(s5));
     typedef void(*virtual_function)(void);
     struct s123_equivalence{
         virtual_function* pVtbl;
     }o123;
     memcpy(&o123,&o1,sizeof(s3));
     printf("s1 vtble address=%p\n",*(int *)o123.pVtbl);  // 此处有问题!
     memcpy(&o123,&o2,sizeof(s3));
     printf("s2 vtble address=%p\n",*(int *)o123.pVtbl);
     memcpy(&o123,&o3,sizeof(s3));
     printf("s3 vtble address=%p\n",*(int *)o123.pVtbl);



     struct s45_equivalence{
         virtual_function* pV1;
         virtual_function* pV2;
     }o45;
     memcpy(&o45,&o4,sizeof(o4));  // 有问题 修改为s4
     printf("s4 vtble address1=%p\n",*(int *)o45.pV1);
     printf("s4 vtble address2=%p\n",*(int *)o45.pV2);

     memcpy(&o45,&o5,sizeof(o5));  // 有问题 修改为s5
     printf("s5 vtble address1=%p\n",*(int *)o45.pV1);
     printf("s5 vtble address2=%p\n",*(int *)o45.pV2);

     return 0; 
}