您的位置:首页 > 其它

非虚继承类,虚继承类的sizeof分析--GCC编译器和VC编译器

2012-10-15 22:00 357 查看
对虚继承层次的对象的内存布局,在不同编译器实现有所区别。(以GCC和VC编译器为例)

GCC编译器:

它实现比较简单,不管是否虚继承,GCC都是将虚表指针在整个继承关系中共享的,不共享的是指向虚基类的指针。

如下例(取自程序员面试宝典(三)P130)

详解:

A中sizeof(int)+sizeof(虚表指针)=8 。

B,C中

如果不是虚继承,下列代码 (I)

sizeof(B)= sizeof(A)+B中元素大小 - B中虚函数表指针大小(4)【因为虚表指针在整个继承关系中是共享的,只需存在A中的虚表指针】= 12;

sizeof(C)同理B;最终为16;

如果是虚继承,下列代码 (II)

相对于非虚继承,sizeof(B)中多了一个虚函数指针(4Byte),而且C中的虚继承指针是不与B共享的。即虚继承指针不共享;

VC编译器:

例子相同:

VC对虚表指针的处理比GCC复杂,它根据是否为虚继承来判断是否在继承关系中共享虚表指针,而对指向虚基类的指针和GCC一样是不共享的

如果为虚继承,则他的继承关系中不会共享虚函数表,而是每个子类维护自己的虚函数表,但是如果不是虚继承,他的继承关系还是共享虚函数表的;

A中sizeof(int)+sizeof(虚表指针)=8 。

B,C中

如果不是虚继承,下列代码 (I)

sizeof(B)= sizeof(A)+B中元素大小- B中虚函数表指针大小(4)【因为虚表指针在整个继承关系中是共享的,只需存在A中的虚表指针】= 12;

sizeof(C)同理B;最终为16;

如果是虚继承,下列代码 (II)

sizeof(B)= sizeof(A)+B中元素大小(包括sizeof(char[3](字节对齐4)+sizeof(虚指针))+ sizeof(虚基类指针)= 20;

C同B分析;

代码(I)

#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <memory.h>
#include <assert.h>

using namespace std;

class A
{
char k[3];
public:
virtual void aa(){};
};
class B : public  A
{

char j[3];
public:
virtual void bb(){};
};
class C : public  B
{
char i[3];
public:
virtual void cc(){};

};

int main(int argc , char *argv[])
{
cout<<"sizeof(A):"<<sizeof(A)<<endl;
cout<<"sizeof(B):"<<sizeof(B)<<endl;
cout<<"sizeof(C):"<<sizeof(C)<<endl;

return 0;
}


GCC编译结果:

sizeof(A):8

sizeof(B):12

sizeof(C):16

Process returned 0 (0x0) execution time : 3.330 s

Press any key to continue.

VC编译结果:

sizeof(A):8

sizeof(B):12

sizeof(C):16

Process returned 0 (0x0) execution time : 0.487 s

Press any key to continue.

代码(II)
#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <memory.h>
#include <assert.h>

using namespace std;

class A
{
char k[3];
public:
virtual void aa(){};
};
class B : public virtual A
{

char j[3];
public:
virtual void bb(){};
};
class C : public virtual B
{
char i[3];
public:
virtual void cc(){};

};

int main(int argc , char *argv[])
{
cout<<"sizeof(A):"<<sizeof(A)<<endl;
cout<<"sizeof(B):"<<sizeof(B)<<endl;
cout<<"sizeof(C):"<<sizeof(C)<<endl;

return 0;
}


GCC编译器输出结果:

sizeof(A):8

sizeof(B):16

sizeof(C):24

Process returned 0 (0x0) execution time : 0.501 s

Press any key to continue.

VC编译器输出结果:



sizeof(A):8

sizeof(B):20

sizeof(C):32

Process returned 0 (0x0) execution time : 0.222 s

Press any key to continue.





内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: