C++对象内存布局-多重继承

2/22/2017来源:ASP.NET技巧人气:460

看《深度探索C++对象模型》有点力不从心。 找到了一篇博客写的很好,把代码跑了一篇,加深了理解 原博客:http://blog.csdn.net/haoel/article/details/3081328

内存分布规则:

每个父类都有自己的虚表。 子类的成员函数被放到了第一个父类的表中。 内存布局中,其父类布局依次按声明顺序排列。 每个父类的虚表中的f()函数都被overwrite成了子类的f()。这样做就是为了解决不同的父类类型的指针指向同一个子类实例,而能够调用到实际的函数。

来看实例: 假设有下面这样一个类的继承关系。注意:子类只重载了父类的f()函数,而还有一个是自己的函数(我们这样做的目的是为了用g1()作为一个标记来标明子类的虚函数表)。而且每个类中都有一个自己的成员变量: 这里写图片描述

代码:

#include<iostream> using namespace std; class Base1 { public: int ibase1; Base1() :ibase1(10) {} virtual void f() { cout << "Base1::f()" << endl; } virtual void g() { cout << "Base1::g()" << endl; } virtual void h() { cout << "Base1::h()" << endl; } }; class Base2 { public: int ibase2; Base2() :ibase2(20) {} virtual void f() { cout << "Base2::f()" << endl; } virtual void g() { cout << "Base2::g()" << endl; } virtual void h() { cout << "Base2::h()" << endl; } }; class Base3 { public: int ibase3; Base3() :ibase3(30) {} virtual void f() { cout << "Base3::f()" << endl; } virtual void g() { cout << "Base3::g()" << endl; } virtual void h() { cout << "Base3::h()" << endl; } }; class Derive : public Base1, public Base2, public Base3 { public: int iderive; Derive() :iderive(100) {} virtual void f() { cout << "Derive::f()" << endl; } virtual void g1() { cout << "Derive::g1()" << endl; } }; int main() { typedef void(*Fun)(void); Fun pFun; Derive d; int** pVtab = (int**)&d; cout << "[0] Base1::_vptr->" << endl; pFun = (Fun)pVtab[0][0]; cout << " [0] "; pFun(); pFun = (Fun)pVtab[0][1]; cout << " [1] "; pFun(); pFun = (Fun)pVtab[0][2]; cout << " [2] "; pFun(); pFun = (Fun)pVtab[0][3]; cout << " [3] "; pFun(); pFun = (Fun)pVtab[0][4]; cout << " [4] "; cout << pFun << endl; cout << "[1] Base1.ibase1 = " << (int)pVtab[1] << endl; int s = sizeof(Base1) / 4; cout << "[" << s << "] Base2::_vptr->" << endl; pFun = (Fun)pVtab[s][0]; cout << " [0] "; pFun(); pFun = (Fun)pVtab[s][1]; cout << " [1] "; pFun(); pFun = (Fun)pVtab[s][2]; cout << " [2] "; pFun(); pFun = (Fun)pVtab[s][3]; cout << " [3] "; cout << pFun << endl; cout << "[" << s + 1 << "] Base2.ibase2 = " << (int)pVtab[s + 1] << endl; s = s + sizeof(Base2) / 4; cout << "[" << s << "] Base3::_vptr->" << endl; pFun = (Fun)pVtab[s][0]; cout << " [0] "; pFun(); pFun = (Fun)pVtab[s][1]; cout << " [1] "; pFun(); pFun = (Fun)pVtab[s][2]; cout << " [2] "; pFun(); pFun = (Fun)pVtab[s][3]; cout << " [3] "; cout << pFun << endl; s++; cout << "[" << s << "] Base3.ibase3 = " << (int)pVtab[s] << endl; s++; cout << "[" << s << "] Derive.iderive = " << (int)pVtab[s] << endl; return 0; }

Derive类的内存布局如下:

这里写图片描述