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

来源:互联网 发布:pb数据窗口列标题修改 编辑:程序博客网 时间:2024/06/17 05:51

看《深度探索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类的内存布局如下:

这里写图片描述

0 0