Cpp 对象模型探索 / 多重继承虚函数表分析

一、源码

#include <iostream>

class Base1
{
public:
    virtual void func11()
    {
        std::cout << "Base1::func11()" << std::endl;
    };
    virtual void func12()
    {
        std::cout << "Base1::func12()" << std::endl;
    }
    virtual void func13()
    {
        std::cout << "Base1::func13()" << std::endl;
    }
    virtual void func14()
    {
        std::cout << "Base1::func14()" << std::endl;
    }
};

class Base2
{
public:
    virtual void func21()
    {
        std::cout << "Base2::func21()" << std::endl;
    }
    virtual void func22()
    {
        std::cout << "Base2::func22()" << std::endl;
    }
    virtual void func23()
    {
        std::cout << "Base2::func23()" << std::endl;
    }
};

class Son : public Base1, public Base2
{
public:
    void func12()
    {
        std::cout << "Son::func12()" << std::endl;
    }
    void func23()
    {
        std::cout << "Son::func23()" << std::endl;
    }
    virtual void son1()
    {
        std::cout << "Son::son1()" << std::endl;
    }
    virtual void son2()
    {
        std::cout << "Son::son2()" << std::endl;
    }
};

using FUNC = void (*)();

int main()
{
    Base1 *pb1 = new Base1();
    Base2 *pb2 = new Base2();
    Son *psn = new Son();

    // 得到两个虚函数表指针的地址。
    long *snptr = (long *)psn;
    long *pvptr1 = snptr;
    long *pvptr2 = snptr + 1;

    // 得到两个虚函数表的指针。
    long *vptr1 = (long *)*pvptr1;
    long *vptr2 = (long *)*pvptr2;

    // 得到所有的虚函数的地址。
    FUNC f1, f2, f3, f4, f5, f6, f7, f8, f9;
    f1 = (FUNC) * (vptr1 + 0);
    f2 = (FUNC) * (vptr1 + 1);
    f3 = (FUNC) * (vptr1 + 2);
    f4 = (FUNC) * (vptr1 + 3);
    f5 = (FUNC) * (vptr1 + 4);
    f6 = (FUNC) * (vptr1 + 5);

    f7 = (FUNC) * (vptr2 + 0);
    f8 = (FUNC) * (vptr2 + 1);
    f9 = (FUNC) * (vptr2 + 2);

    // 执行。
    std::cout << "虚函数表1" << std::endl;
    f1();
    f2();
    f3();
    f4();
    f5();
    f6();
    std::cout << std::endl;

    std::cout << "虚函数表2" << std::endl;
    f7();
    f8();
    f9();

    std::cin.get();

    return 0;
}

结果:

虚函数表1
Base1::func11()
Son::func12()
Base1::func13()
Base1::func14()
Son::son1()
Son::son2()

虚函数表2
Base2::func21()
Base2::func22()
Son::func23()

二、分析

三、结论

  1. 对于继承了多个带有虚函数的父类的子类来说,该类有多个虚函数表,虚函数表的数量和父类的数量相同。
  2. 若子类存在虚函数,那么这些虚函数的地址会放在继承的第一个父类的虚函数表中,即:子类和第一个父类公用一个虚函数表,虚函数地址罗列顺序是虚函数声明顺序。
  3. 类对象有多个虚函数表指针,数量和父类的数量相同。这些虚函数表指针会依次放到子类对象的开始位置。

 

(SAW:Game Over!)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值