• 虚函数表与动态绑定


    多态

    1、方法重写:子类可以重写父类的函数
    2、向上类型转换:用一个父类指针指向子类对象的时候,假如调用的是虚函数,会自动暂时的将该指针转换为子类类型

    虚函数的作用就是指针类型转换,但即使没有虚函数也可以重写方法

    虚函数表 与虚函数

    虚表是什么:只是一个数组,里面的每个元素存放的是虚函数的地址。
    虚指针是什么:只是一个指针,指向虚表。

    需要特别注意的是:虚表是对于类而言的,虚指针则是针对对象而言的。

    也就是说,可以认为虚表内存存在于类内存中(代码区),每一个类只需要一份就可以了。虚指针则存在于对象的内存(堆栈区)里,每一个对象就有一个虚指针。假如某个类实例化了10000个对象,那么虚指针就要占用10000*8字节(假设每个指针占用8字节),而虚表的占用内存则完全不变。

    注意:每一个实例化的对象里面都有一个虚指针,要是编译器发现这个对象要调用虚函数,虚指针就会指向该对象类的虚函数表,去寻找虚函

    我们只要当p指向父类对象的时候,指向的是父类的vptr;当p指向父类对象的时候,指向的是子类的vptr

    在这里插入图片描述

    虚函数表的具体实现

    当一个类里存在虚函数时,编译器会为类创建一个虚函数表vtable,虚函数表是一个数组,数组的元素存放的是类中虚函数的地址。
    编译器还会在**对象的存储空间中安插一个指针vfptr,**指向虚函数表数组的起始位置
    每一个有虚函数的类都有一个虚函数表,虚函数是整个类所共有的,虚函数表存储在对象内存最开始的位置。如果子类继承了多个父类,并且父类有虚函数,则子类要存储多个虚函数指针。

    请添加图片描述
    1、基类base里面最初的虚函数表
    请添加图片描述
    2、当子类Node继承基类base但是没有将虚函数重写,Node的虚函数表
    请添加图片描述
    3、当子类Node覆盖了基类的虚函数,Node的虚函树表
    父类被覆盖的函数f(),都被替换为子类的虚函数f()
    请添加图片描述

    动态绑定

    //基类
    class Base{
    public:
        virtual void func();
    protected:
        int m_a;
        int m_b;
    };
    void Base::func(){ cout<<"调用基类"<<endl; }
    
    //派生类
    class Derived: public Base{
    public:
        void func();
    private:
        int m_c;
    };
    void Derived::func(){ cout<<"调用子类"<<endl; }
    int main(){
        Base *p;
        int n;
    
        cin>>n;//用户操作不同,p指向的对象类型不同
        
        if(n <= 100){
            p = new Base();
        }else{
            p = new Derived();
        }
        cout<<typeid(*p).name()<<endl;
        return 0;
    }
    
    

    输入 45,运行结果为:
    45↙
    基类

    输入 130,运行结果为:
    130↙
    子类

    同一个虚函数,会根据我们指针指向不同对象去对找到对应的虚函数表,然后绑定我们需要的虚函数

  • 相关阅读:
    六、 JavaScript:BOM对象
    用powerquery实现SQL开窗函数取数功能
    【读书笔记】《我在北京送快递》——记录的意义
    十全十美源码
    PPOCRLabel 半标注工具全平台安装使用
    为什么电商创业者2022年都在做抖音小店无货源?揭开抖店无货源玩法
    【Javascript保姆级教程】if判断语句的三种形式
    基于JavaSwing开发单位固定资产登记管理系统 毕业设计 课程设计 大作业
    36.cuBLAS开发指南中文版--cuBLAS中的Level-2函数hpmv()
    Day20.1:关于this、super的解析
  • 原文地址:https://blog.csdn.net/qq_43448818/article/details/127071112