在只有虚函数,或者只有虚继承的情况下,各个编译器中对C++的内存模型的实现是一样的。但同时存在虚函数和虚继承时,GCC与VC就会有差别。
class Base//4 { int a; }; class Base1 :public Base//8 { int a; }; class Base2 : public Base//8 { int a; }; class Base3//4 { virtual void funa(){} }; //两个虚继承分别使用两个指针指向自己的虚基类,然后两个基类有2个int //应为使用了共同的虚基类,base的int只有一个,因此2*4+4+4+4=20 //有多个虚继承的时候,就有多个虚指针 class Derve:public virtual Base1,virtual Base2//20 { }; //base1有2个a,base2有两个a,就是基类的a有两份 class Derve0:public Base1, Base2//16 base1有2个a,base2有两个a, { }; class Derve1:public Derve//20 { }; class Derve2:public Derve//24 { int a; }; //GCC当中 虚基类指针也会并入虚表中,VC不会,所有VC是24 class Derve3:public Derve//24 -- 20 { virtual void fun(){} }; //多个虚继承共用一个虚表,一个虚指针 class Derve4:public Base3//4 { virtual void fun(){} }; ////GCC当中 虚基类指针也会并入虚表中,所以只有一个虚指针,VC是12 class Derve5:virtual public Base3//12 -- 8 { int a; }; class Derve6:public Derve3//24,VC28 { virtual void fun(){} int a; };
总结:
1、多个虚函数共用一个虚表
2、多个虚继承会建立多个虚表,因此会有多个虚指针
3、在GCC中,如果同时有虚继承和虚函数,则指向虚基类的指针也会放在虚表中,就是每个虚继承只有一个虚指针;但多个虚继承仍然会有多个虚指针。
4、在VC中,虚函数指针与虚基类指针不会合并,同时存在。如Derve3例子