非虚继承类,虚继承类的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)
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)
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.
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.
相关文章推荐
- [C] 让VC支持C99的整数类型V1.01。避免包含目录问题,更名auto_stdint.h、auto_inttypes.h(在VC6至VC2012、GCC、BCB等编译器下测试通过)
- 虚表结构与虚继承内存对象模型(gcc vs vc)
- VC sizeof(struct)内存分配分析
- GCC 在模板继承中不可理解的地方(编译器问题)
- 从编译器的角度分析继承中的虚函数
- 发现VC编译器和gcc编译器的一点不同
- gcc和vc编译器区别
- 【转】gcc和vc编译器在语法上的比较
- std::async在gcc和vc不同编译器下的不同表现(可能会阻塞)
- gcc和vc编译器在语法上的比较
- sizeof,真正终结版GCC与VC
- GCC编译器优化选项分析及具体优化了什么
- VC编译器下的 setjmp 和 longjmp 的32位程序分析
- (转)gcc编译与vc编译器区别
- C++带有虚函数的单继承类的构造过程探索,msvc和gcc编译器
- (转)gcc编译与vc编译器区别
- gcc和vc编译器在语法上的比较(转)
- GCC编译器优化选项分析及具体优化了什么
- C++对象内存布局--⑧GCC编译器--虚拟继承多个基类
- gcc编译与vc编译器区别