计算虚继承中对象占用的空间
请写出sizeof的运算结果
程序1
class Base{ void f(){} }; class Derived1:public Base{ void f1(){} }; class Derived2:public virtual Base{ void f2(){} }; sizeof(Base); sizeof(Derived1); sizeof(Derived2);
答案:1, 1, 4
问题分析:
Base类没有任何数据成员,但是Base类的对象占用的空间却不是0,由于对象存储在内存中,不占用空间的对象在内存中无法标识,因此Base类的对象在内存中会有一个占位符,占用空间为1个字节。
Derived1类继承Base类,没有任何数据成员,因此Derived1类的对象也只有一个占位符,占用空间为1个字节。
Derived2类虚继承Base类,没有任何数据成员,但是由于虚继承的关系,Derived2类的对象中会有一个指向虚基类Base的指针,指针占用的空间为4个字节,因此Derived2类的对象占用空间为4个字节。
程序2
class Base{ virtual void f(){} }; class Derived1:public Base{ virtual void f1(){} }; class Derived2:public Base{ virtual void f2(){} }; class Derived3:public virtual Base{ virtual void f3(){} }; sizeof(Base); sizeof(Derived1); sizeof(Derived2); sizeof(Derived3);
答案:4, 4, 4, 8(GCC)或12(VC)
问题分析:
Base 类中没有任何数据成员,但是由于Base类中有虚函数,Base类的对象中会有一个指向虚函数表的指针,因此Base类的对象占用空间为4个字节。
Derived1类继承Base类,没有任何数据成员,但是Derived1类继承了Base类中的虚函数,使得Derived1类的对象中也含有一个指向虚函数表的指针,因此Derived1类的对象占用空间为4个字节。
Derived2类继承Base类,没有任何数据成员,但是Derived2类不但继承了Base类的虚函数,还有自己的虚函数,这两个虚函数关联同一个虚函数表,因此Derived2类的对象中只有一个指向虚函数表的指针,占用4个字节。
Derived3类虚继承Base类,这个情况比较复杂,不同编译器的实现不同。这里只分析一下主流的VC编译器和GCC编译器。
对于VC编译器来说,虚继承中父类和子类不共享指向虚函数表的指针,因此Derived3类的对象中有三个指针:指向Base类虚函数表的指针,指向Derived3类虚函数表的指针,指向虚基类Base的指针,总共占用空间为12个字节。
对于GCC编译器来说,无论普通继承还是虚继承,任何对象只有一个指向虚函数表的指针,因此Derived3类的对象中有两个指针:指向虚函数表的指针,指向虚基类Base的指针,总共占用空间为8个字节。