继承和虚函数、虚基类的类型大小的比较

来源:互联网 发布:我的世界编程教程 编辑:程序博客网 时间:2024/04/29 10:02

        第一种情况:一个空类

class A {};

其类型大小是sizeof(A)等于1,即占有一个字节。原因是因为每个对象必须必须在内存中配置独一无二的地址,因此编译器默认为该类提供了一个char类型的数据成员,使该空类的大小为1byte。

 

        第二种情况:有一个派生类的情况,且派生类也是空类

class A {};class B : public A {};

由于编译器的优化,sizeof(B)大小也是1byte

     

        第三种情况:基类有数据成员

class A {    int x;};class B : public A {};


现在 sizeof(A)的大小是4bytes(32位机器上,以下相同),sizeof(B)的大小也是4bytes,因为它含有从基类继承过来的数据成员。

 

        第四种情况:基类有虚函

class A {public:virtual void Print();};class B : public A {};

sizeof(A)的大小是4bytes,这是由于虚机制导致编译器为每个类对象生成一个虚函数指针。sizeof(B)的大小也是4bytes,因为它继承了基类的虚函数,也继承了基类的虚函数指针,不过派生类的虚函数指针要从新初始化,指向派生类的虚函数列表。

 

        第五中情况:菱形多继承

class A {};class B : public A {};class C : public A {};class D : public B, public C {};

类A,B,C,D的大小均为1byte,这里同第二种情况一样。

 

        第六种情况:菱形多继承中,顶层基类有数据成员

class A {    int a;};class B : public A {};class C : public A {};class D : public B, public C {};

这里类A,B,C的大小均为4bytes,类D的大小是8bytes。类D继承了类B和类C,B和C又都分别继承了A,因此在类D中有类A的两个实例,即两个整形数据成员a,因此大小是8bytes。

 

        第七种情况,虚基类的继承----基类是空类

class A {    //int a;};class B : virtual public A {};class C :  virtual public A {};class D : public B, public C {};

这里类A的大小还是1byte,由于虚机制,编译器会为每个类B和类C的对象生成一个虚指针,因此B和C的大小都是4bytes。 类D两个基类B和C的虚指针都会继承,因此在D的内部有两个指针,大小为8bytes。

 

        第八种情况:虚基类的继承----基类有数据成员

class A {    int a;};class B : virtual public A {};class C :  virtual public A {};class D : public B, public C {};

这里类A的大小是4bytes,类B和类C的大小都是由编译器产生的虚指针大小和继承的基类A的数据成员大小再加上字节对齐(这里正好是对齐的),因此大小都是8bytes。  对于类D虽然继承了类A两次,但是是虚继承的,所以编译器只为类A实例化一次,因此类D的大小就是继承的类A的数据成员和继承的类B的虚指针和类C的虚指针再加上字节对齐,就是12bytes。

        不同的编译器对内存字节对齐的要求是不一样的。如果将类A的整形数据成员改成char类型,在vs2010的输出结果就是:

在wxDev-C++中的输出结果就是:


 

 




 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0 0
原创粉丝点击