虚表结构与虚继承内存对象模型
来源:互联网 发布:ubuntu安装解压软件 编辑:程序博客网 时间:2024/05/23 12:52
很好的一篇关于特定编译器的对象模型介绍,恰到好处,重新排版,原文地址:
http://www.cnblogs.com/qlee/archive/2011/09/02/2163504.html
最近看了下Inside C++里面讲的对虚继承层次的对象的内存布局,发现在不同编译器实现有所区别。因此,自己动手探索了一下。结果如下:
首先,说说GCC的编译器.
它实现比较简单,不管是否虚继承,GCC都是将虚表指针在整个继承关系中共享的,不共享的是指向虚基类的指针。
#include <iostream>using namespace std;class A {public:int a;virtual ~A(){}};class B:virtual public A{public:virtual ~B(){}virtual void myfunB(){}};class C:virtual public A{public:virtual ~C(){}virtual void myfunC(){}};class D:public B,public C{public:virtual ~D(){}virtual void myfunD(){}};int main(){ cout << sizeof(A) << endl; cout << sizeof(B) << endl; cout << sizeof(C) << endl; cout << sizeof(D) << endl;}
以上代码中 sizeof(A)=8,sizeof(B)=12,sizeof(C)=12,sizeof(D)=16.(GCC结果)
解释:A中int+虚表指针。B,C中由于是虚继承因此大小为A+指向虚基类的指针,B,C虽然加入了自己的虚函数,但是虚表指针是和基类共享的,因此不会有自己的虚表指针。D由于B,C都是虚继承,因此D只包含一个A的副本,于是D大小就等于A+B中的指向虚基类的指针+C中的指向虚基类的指针。
如果B,C不是虚继承,而是普通继承的话,那么A,B,C的大小都是8(没有指向虚基类的指针了),而D由于不是虚继承,因此包含两个A副本,大小为16. 注意此时虽然D的大小和虚继承一样,但是内存布局却不同。
然后来看看VC的编译器
vc对虚表指针的处理比GCC复杂,它根据是否为虚继承来判断是否在继承关系中共享虚表指针,而对指向虚基类的指针和GCC一样是不共享,当然也不可能共享。
代码同上。
运行结果将会是sizeof(A)=8,sizeof(B)=16,sizeof(C)=16,sizeof(D)=24.(VC结果)
解释:A中依然是int+虚表指针。B,C中由于是虚继承因此虚表指针不共享,由于B,C加入了自己的虚函数,所以B,C分别自己维护一个虚表指针,它指向自己的虚函数。(注意:只有子类有新的虚函数时,编译器才会在子类中添加虚表指针)因此B,C大小为A+自己的虚表指针+指向虚基类的指针。D由于B,C都是虚继承,因此D只包含一个A的副本,同时D是从B,C普通继承的,而不是虚继承的,因此没有自己的虚表指针。于是D大小就等于A+B的虚表指针+C的虚表指针+B中的指向虚基类的指针+C中的指向虚基类的指针。
同样,如果去掉虚继承,结果将和GCC结果一样,A,B,C都是8,D为16,原因就是VC的编译器对于非虚继承,父类和子类是共享虚表指针的。
- 虚表结构与虚继承内存对象模型
- 虚表结构与虚继承内存对象模型
- 虚表结构与虚继承内存对象模型
- 虚表结构与虚继承内存对象模型(gcc vs vc)
- 虚继承与虚基类中对象的内存模型分析
- C++虚继承内存对象模型探讨
- C++虚继承内存对象模型探讨
- C++虚继承内存对象模型探讨
- C++虚继承内存对象模型探讨
- C++虚继承内存对象模型探讨
- C++虚继承内存对象模型探讨
- 虚继承内存布局@c++对象模型
- C++虚继承内存对象模型探讨
- C++对象内存模型(高级)—多重继承与虚函数表(转)
- 多继承(虚继承)派生类对象内存结构
- [C++对象模型]虚继承与虚函数表
- [C++对象模型][9]虚继承与虚函数表
- [C++对象模型][9]虚继承与虚函数表
- 《深入java虚拟机》学习笔记(第七章 类型的生命周期)
- HEVC/H.265整个程序调用流程分析以及函数复杂度分析
- 使用PowerDesigner画ER图详细教程
- Java程序员应该知道的10个调试技巧(转)
- iOS 使用Block
- 虚表结构与虚继承内存对象模型
- httpclient 参数 覆盖级别
- VS2008快捷键
- java多线程
- VC++实现获取DNS服务器
- ssh连接linux sz|rz(文件传输工具)
- U_boot 的 bootcmd 和bootargs参数详解
- 9-4
- xtrabackup-1.6.5备份详解