C++内存模型之虚函数表

概述
  • 实现多态,C++使用了一种动态绑定的技术,这个技术的核心是“虚函数表”
类的虚函数表
  • 每个包含虚函数的都包含一个虚函数表

  • 虚函数表是一个指针数组,其元素是虚函数的指针,每个元素对应一个虚函数的函数指针

  • 虚函数表内的元素,即虚函数指针的赋值发生在编译器的编译阶段,虚函数表就可以构造出来了

虚函数表指针
  • 虚函数表是属于类的,而不是属于某个具体的对象,一个类只需要一个虚函数表即可,同一个类的所有对象都使用同一个虚函数表

  • 对象内部包含一个虚函数表的指针,来指向自己所使用的虚函数表(*_vptr)

  • 类的对象在创建时便拥有了这个指针,且这个指针的值会自动被设置为指向类的虚函数表

  • 一个类对象只有自身所属虚函数表的指针(而不是继承的类的虚函数表)

动态绑定
class A {
public:
    virtual void vfunc1();
    virtual void vfunc2();
    void func1();
    void func2();
private:
    int m_data1, m_data2;
};
class B : public A {
public:
    virtual void vfunc1();
    void func1();
private:
    int m_data3;
};
class C: public B {
public:
    virtual void vfunc2();
    void func2();
private:
    int m_data1, m_data4;
};
  • 上述代码对应图表
    在这里插入图片描述

  • 子类重写基类的虚函数之后则不再指向基类虚函数,而指向自身实现作用域的虚函数;反之未被重写的虚函数,子类则依旧指向基类作用域的虚函数

  • 虚函数表的指针会指向其直接继承的基类的虚函数

    int main() 
    {
        B bObject;
        A *p = & bObject;  // 多态
    }
    
  • B对象在创建时,它的虚函数表指针已经设置为指向B vtbl,声明A的指针来指向对象B,虽然p是基类的指针只能指向基类部分,但是虚函数表指针亦属于基类部分,所以p可以访问到对象b的虚函数表指针

    int main() 
    {
        A aObject;
        A *p = &aObject;
        p->vfunc1();
    }
    
    • 实际上可以看作(*(p->__vptr)[n])(p)
  • 执行动态绑定的条件

  1. 通过指针来调用函数
  2. 指针upcast向上转型(继承类向基类的转换称为upcast)
  3. 调用的是虚函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值