标签:c++虚继承内存分布 c++对象内存分布 c++内存分布
本篇文章的所有代码例子,如果是windows上编译运行,则使用的是visual studio 2013。如果是RHEL6.5平台(linux kernal: 2.6.32-431.el6.i686)上编译运行,则其gcc版本为4.4.7,如下所示:
[root@MiWiFi-R1CM ~]# gcc --version
gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-4)
本篇文章主要讨论的是虚继承(virtual)下的内存分布。
下面的代码运行在windows 7+visual studio 2013平台上。
分别打印类Base1对象的内存分布,和类Derive对象的内存分布。
#include <iostream> using namespace std; class Base { public: int _iBase; char _cBase; public: Base() : _iBase(1111), _cBase('A') { } virtual void func() { cout << "Base::func()" << endl; } virtual void baseFunc() { cout << "Base::baseFunc()" << endl; } }; class Base1 : public virtual Base { public: int _iBase1; char _cBase1; public: Base1() : _iBase1(2222), _cBase1('B') { } virtual void func() { cout << "Base1::func()" << endl; } virtual void func1() { cout << "Base1::func1()" << endl; } virtual void baseFunc1() { cout << "Base1::baseFunc1()" << endl; } }; class Base2 : public virtual Base { public: int _iBase2; char _cBase2; public: Base2() : _iBase2(3333), _cBase2('C') { } virtual void func() { cout << "Base2::func()" << endl; } virtual void func2() { cout << "Base2::func2()" << endl; } virtual void baseFunc2() { cout << "Base2::baseFunc2()" << endl; } }; class Derive : public virtual Base1, public virtual Base2 { public: int _iDerive; char _cDerive; public: Derive() : _iDerive(4444), _cDerive('D') { } virtual void func() { cout << "Derive::func()" << endl; } virtual void func1() { cout << "Derive::func1()" << endl; } virtual void func2() { cout << "Derive::func2()" << endl; } virtual void deriveFunc() { cout << "Derive::deriveFunc()" << endl; } }; typedef void(*Fun)(); int main() { int **pVtab = NULL; Fun pFun = NULL; Base1 bb1; cout << "sizeof(Base)" << sizeof(Base) << endl; cout << "sizeof(Base1)" << sizeof(Base1) << endl; //Base1 layout pVtab = (int**)&bb1; cout << "[0] Base1::_vptr->" << " addr:" << &pVtab[0] << endl; pFun = (Fun)pVtab[0][0]; cout << " [0]"; pFun(); //Base1::func1() pFun = (Fun)pVtab[0][1]; cout << " [1]"; pFun(); //Base1::baseFunc1() cout << " [2]"; cout << pVtab[0][2] << endl; cout << "[1] Base1::_vbptr->" << " addr:" << &pVtab[1] << endl; cout << " [0]"; cout << pVtab[1][0] << endl; cout << " [1]offset->"; cout << pVtab[1][1] << endl; cout << " [2]"; cout << pVtab[1][2] << endl; cout << "[2] Base1:_iBase1 -> "; cout << (int)pVtab[2] << endl; //Base1:_iBase1 cout << "[3] Base1:_cBase1 -> "; cout << (char)(int)pVtab[3] << endl; //Base1:_cBase1 cout << "[4] unknown "; cout << (int)pVtab[4] << endl; cout << "[5] Base::_vfptr->" << " addr:" << &pVtab[4] << endl; cout << " [0]"; pFun = (Fun)pVtab[5][0]; pFun(); cout << " [1]"; pFun = (Fun)pVtab[5][1]; pFun(); cout << " [2]"; cout << (int)pVtab[5][2] << endl; cout << "[6] Base:_iBase -> "; cout << (int)pVtab[6] << endl; //Base:_iBase cout << "[7] Base:_cBase -> "; cout << (char)(int)pVtab[7] << endl; //Base:_cBase cout << endl; cout << "###########################" << endl; cout << endl; //Derive layout // sub Derive vtbl layout Derive d; cout << "sizeof(Derive)" << sizeof(Derive) << endl; pVtab = (int**)&d; cout << "[0] Derive::_vfptr->" << " addr:" << &pVtab[0] << endl; cout << " [0] "; pFun = (Fun)pVtab[0][0]; pFun(); //Derive::func1(); cout << " [1] "; cout << pVtab[0][1] << endl; cout << "[1] Derive::_vbptr->" << " addr:" << &pVtab[1] << endl; cout << " [0] "; cout << pVtab[1][0] << endl; cout << " [1]offset-> "; cout << pVtab[1][1] << endl; cout << " [2] "; cout << pVtab[1][2] << endl; cout << " [3] "; cout << pVtab[1][3] << endl; cout << " [4] "; cout << pVtab[1][4] << endl; cout << "[2] Derive::_iDerive -> "; cout << (int)pVtab[2] << endl; //Derive:_iDerive cout << "[3] Derive::_cDerive -> "; cout << (char)(int)pVtab[3] << endl; //Derive::_cDerive cout << "[4] unknown-> " << (int)pVtab[4] << endl; // sub Base vtbl layout cout << "[5] Base::_vfptr->" << " addr:" << &pVtab[5] << endl; cout << " [0] "; pFun = (Fun)pVtab[5][0]; pFun(); pFun = (Fun)pVtab[5][1]; cout << " [1] "; pFun(); cout << " [2] "; cout << pVtab[5][2] << endl; cout << "[6] Base::_iBase -> "; cout << (int)pVtab[6] << endl; cout << "[7] Base::_cBase -> "; cout << (char)(int)pVtab[7] << endl; cout << "[8] unknown-> "; cout << (int)pVtab[8] << endl; // sub Base1 vtbl layout cout << "[9] Base1::_vfptr->" << " addr:" << &pVtab[9] << endl; cout << " [0] "; cout << pVtab[9][0] << endl; pFun = (Fun)pVtab[9][1]; cout << " [1] "; pFun(); pFun = (Fun)pVtab[9][2]; cout << " [2] "; cout << (int)pFun << endl; pFun = (Fun)pVtab[9][3]; cout << " [3] "; cout << (int)pFun << endl; cout << "[10] unknown-> "; cout << (int)pVtab[10] << endl; cout << "[11] Base1::_iBase1 -> "; cout << (int)pVtab[11] << endl; cout << "[12] Base1::_cBase1 -> "; cout << (char)(int)pVtab[12] << endl; cout << "[13] unknown-> "; cout << (int)pVtab[13] << endl; // sub Base2 vtbl layout cout << "[14] Base2::_vfptr->" << " addr:" << &pVtab[14] << endl; cout << " [0] "; cout << pVtab[14][0] << endl; pFun = (Fun)pVtab[14][1]; cout << " [1] "; pFun(); cout << " [2] "; cout << pVtab[14][2] << endl; cout << " [3] "; cout << pVtab[14][3] << endl; cout << "[15] unknown-> "; cout << (int)pVtab[15] << endl; cout << "[16] Base2::_iBase2 -> "; cout << (int)pVtab[16] << endl; cout << "[17] Base2::_cBase2 -> "; cout << (char)(int)pVtab[17] << endl; return 0; }
Base1对象的内存分布为:
Derive对象的内存分布为:
下面代码中,对于这4个类的定义,与前面的windows代码中对类的定义是完全一样的,所以这里省略掉了。只列出用于输出内存分布的代码:
int main() { int **pVtab = NULL; Fun pFun = NULL; Base1 bb1; cout << "sizeof(Base)" << sizeof(Base) << endl; cout << "sizeof(Base1)" << sizeof(Base1) << endl; //Base1 layout pVtab = (int**)&bb1; cout << "[0] Base1::_vptr->" << " addr:" << &pVtab[0] << endl; pFun = (Fun)pVtab[0][0]; cout << " [0]"; pFun(); //Base1::func1() pFun = (Fun)pVtab[0][1]; cout << " [1]"; pFun(); //Base1::baseFunc1() pFun = (Fun)pVtab[0][2]; cout << " [2]"; pFun(); cout << " [3]"; cout << pVtab[0][3]; cout << "[1] Base1:_iBase1 -> "; cout << (int)pVtab[1] << endl; //Base1:_iBase1 cout << "[2] Base1:_cBase1 -> "; cout << (char)(int)pVtab[2] << endl; //Base1:_cBase1 // Base layout cout << "[3] Base::_vptr->" << " addr:" << &pVtab[3] << endl; pFun = (Fun)pVtab[3][0]; cout << " [0]"; pFun(); //Base1::func() pFun = (Fun)pVtab[3][1]; cout << " [1]"; pFun(); //Base::baseFunc() cout << " [2]"; cout << pVtab[3][2] << endl; cout << "[4] Base:_iBase -> "; cout << (int)pVtab[4] << endl; //Base:_iBase cout << "[5] Base:_cBase -> "; cout << (char)(int)pVtab[5] << endl; //Base:_cBase cout << "[6] " << (int)pVtab[6] << " addr:" << &pVtab[6] << endl; //dirty data cout << endl; cout << "###########################" << endl; cout << endl; // Derive layout // sub Derive vtbl layout Derive d; cout << "sizeof(Derive)" << sizeof(Derive) << endl; pVtab = (int**)&d; cout << "[0] Derive::_vfptr->" << " addr:" << &pVtab[0] << endl; cout << " [0] "; pFun(); //Derive::func1(); pFun = (Fun)pVtab[0][1]; cout << " [1] "; pFun(); //Base1::baseFunc1(); pFun = (Fun)pVtab[0][2]; cout << " [2] "; pFun(); //Derive::deriveFunc(); pFun = (Fun)pVtab[0][3]; cout << " [3] "; pFun(); cout << " [4] "; cout << pVtab[0][4] << endl; cout << "[1] Derive:_iDerive -> "; cout << (int)pVtab[1] << endl; //Derive:_iDerive cout << "[2] Derive:_cDerive -> "; cout << (char)(int)pVtab[2] << endl; //Derive:_cDerive // sub Base1 vtbl layout cout << "[3] Base1::_vptr->" << " addr:" << &pVtab[3] << endl; pFun = (Fun)pVtab[3][0]; cout << " [0] "; pFun(); pFun = (Fun)pVtab[3][1]; cout << " [1] "; pFun(); pFun = (Fun)pVtab[3][2]; cout << " [2] "; pFun(); cout << " [3] "; cout << pVtab[3][3] << endl; cout << "[4] Base1::_iBase1 -> "; cout << (int)pVtab[4] << endl; cout << "[5] Base1::_cBase1 -> "; cout << (char)(int)pVtab[5] << endl; // sub Base vtbl layout cout << "[6] Base::_vptr->" << " addr:" << &pVtab[6] << endl; pFun = (Fun)pVtab[6][0]; cout << " [0] "; pFun(); pFun = (Fun)pVtab[6][1]; cout << " [1] "; pFun(); pFun = (Fun)pVtab[6][2]; cout << " [2] "; cout << (int)pFun << endl; cout << "[7] Base::_iBase -> "; cout << (int)pVtab[7] << endl; cout << "[8] Base::_cBase -> "; cout << (char)(int)pVtab[8] << endl; // sub Base2 vtbl layout cout << "[9] Base2::_vptr->" << " addr:" << &pVtab[9] << endl; pFun = (Fun)pVtab[9][0]; cout << " [0] "; pFun(); pFun = (Fun)pVtab[9][1]; cout << " [1] "; pFun(); pFun = (Fun)pVtab[9][2]; cout << " [2] "; pFun(); cout << " [3] "; cout << pVtab[9][3] << endl; cout << "[10] Base2::_iBase2 -> "; cout << (int)pVtab[10] << endl; cout << "[11] Base2::_cBase2 -> "; cout << (char)(int)pVtab[11] << endl; return 0; }Base1对象的内存分布为:
Derive对象的内存分布为:
Windows 7 + Visual studio 2013 Linux RHEL6.5 + gcc 4.4.7
Windows 7 + Visual studio 2013 Linux RHEL6.5 + gcc 4.4.7
在前面的章节(2.5)中,已经列出了Derive在虚继承(virtual)的情况下,在windows以及linux平台下的详细内存分布。
在前一篇文章中,我们获得了非虚继承(non virtual)的情况下,Derive类的内存分布。这里将它与本篇文章中获得的虚继承的分布,进行一个对比。
下图是windows平台下,非虚继承与虚继承对类的内存分布的影响对比。
非虚继承(non virtual) 虚继承(virtual)
下图是linux平台下,非虚继承与虚继承对类的内存分布的影响对比。
非虚继承(non virtual) 虚继承(virtual)
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:c++虚继承内存分布 c++对象内存分布 c++内存分布
原文地址:http://blog.csdn.net/shltsh/article/details/46654645