C++对象模型(存在虚函数与虚继承的情况)

//C++对象模型
//存在虚函数与虚继承的情况


#include <iostream>
using namespace std;

typedef void (*FUNC)();
FUNC fun;
#define PRT(x) cout<<x<<endl
#define RUN(x) fun = (FUNC)x; \
               fun()

class BB
{
public:
    BB():bb_(0xbb)
    {

    }
    virtual void vfbb()
    {
        PRT("BB::vfbb()...");
    }
    virtual void vfbb2()
    {
        PRT("BB::vfbb2()...");
    }
    int bb_;
};

class B1:virtual public BB
{
public:
    B1():b1_(0xb1)
    {

    }
    virtual void vfb1()
    {
        PRT("B1::vfb1()...");
    }
    int b1_;
};

class B2:virtual public BB
{
public:
    B2():b2_(0xb2)
    {

    }
    virtual void vfb2()
    {
        PRT("B2::vfb2()...");
    }
    int b2_;
};

class DD:public B1, public B2
{
public:
    DD():dd_(0xdd)
    {

    }
    virtual void vfdd()
    {
        PRT("DD::vfdd()...");
    }
    int dd_;
};

int main()
{
    long** p;
    PRT(sizeof(BB));//8
    PRT(sizeof(B1));//20
    PRT(sizeof(B2));//20
    PRT(sizeof(DD));//36


    PRT("------BB------");
    BB bb;
    //PRT(&bb);
    //PRT(&bb.bb_);
    p = (long**)&bb;
    RUN(p[0][0]);              //BB::vfbb()
    RUN(p[0][1]);              //BB::vfbb2()

    PRT("------B1------");
    B1 b1;
    //PRT(&b1);
    //PRT(&b1.b1_);
    //PRT(&b1.bb_);
    p = (long**)&b1;
    RUN(p[0][0]);              //B1::vfb1()
    PRT(p[1][0]);              //-4
    PRT(p[1][1]);              //8
    PRT(p[2]);
    RUN(p[3][0]);              //BB::vfbb()
    RUN(p[3][1]);              //BB::vfbb2()
    PRT(p[4]);

    PRT("------DD------");
    DD dd;
    //PRT(&dd);
    //PRT(&dd.b1_);
    //PRT(&dd.b2_);
    //PRT(&dd.dd_);
    //PRT(&dd.bb_);

    p = (long**)&dd;
    RUN(p[0][0]);              //B1::vfb1()
    RUN(p[0][1]);              //DD::vfdd()
    PRT(p[1][0]);              //-4
    PRT(p[1][1]);              //24
    PRT(p[2]);
    RUN(p[3][0]);              //B2::vfb2()
    PRT(p[4][0]);              //-4
    PRT(p[4][1]);              //12
    PRT(p[5]);
    PRT(p[6]);
    RUN(p[7][0]);              //BB::vfbb()
    RUN(p[7][1]);              //BB::vfbb2()
    PRT(p[8]);
    return 0;
}



/*
内存模型
    BB
+---------+虚表指针指向虚表  vtbl
|  vptr   |--------------->+-----------+
+---------+                |BB::vfbb() |虚函数入口地址
|  bb_    |                +-----------+
+---------+                |BB::vfbb2()|
                           +-----------+

    B1
+---------+      虚表指针指向虚表               vtbl
|  vptr   |------------------------------->+-----------+
+---------+                                |B1::vfb1() |
|  vbptr  |---+虚基类表指针指向虚基类表    +-----------+
+---------+   |      vbtl
|   b1_   |   +-->+---------+
+---------+       |  -4     |本类地址与虚基类表指针地址的差,如果没有虚函数(虚表)则为0
|  vptr   |---+   +---------+
+---------+   |   |  8      |虚基类地址与虚基类表指针地址的差
|   bb_   |   |   +---------+                  vtbl
+---------+   +--------------------------->+-----------+
                       虚表指针指向虚表     |BB::vfbb() |
 如果是非虚继承则B1中的两个虚表将合并为一个   +-----------+
                                           |BB::vfbb2()|
                                           +-----------+



    DD
+---------+                                   vtbl
|  vptr   |------------------------------->+-----------+
+---------+                 vbtl           |B1::vfb1() |
|  vbptr  |------------->+----------+      +-----------+
+---------+              |  -4      |      |DD::vfdd() |
|   b1_   |              +----------+      +-----------+
+---------+              |  24      |
|  vptr   |----------+   +----------+         vtbl
+---------+          +-------------------->+-----------+
|  vbptr  |-------+         vbtl           |B2::vfb2() |
+---------+       +----->+----------+      +-----------+
|   b2_   |              |  -4      |
+---------+              +----------+
|   dd_   |              |  12      |
+---------+              +----------+         vtbl
|  vptr   |------------------------------->+-----------+
+---------+                                |BB::vfbb() |
|   bb_   |                                +-----------+
+---------+                                |BB::vfbb2()|
                                           +-----------+
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值