• 虚函数表与动态绑定


    多态

    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↙
    子类

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

  • 相关阅读:
    Neo4j在linux上的安装与Springboot的集成
    windows离线部署VSCode在Centos7上的远程开发环境
    【Python/Pytorch 】-- SVM算法
    最大流之上下界可行流
    个人作品录
    如何在IDEA上使用Git克隆下载创建好的项目和分支、提交项目
    oracle OCP OCM MySQL OCP认证难吗?
    微服务框架 SpringCloud微服务架构 5 Nacos 5.3 服务多级存储模型
    Windows 11 现已正式推出!
    吴恩达开新课了:面向所有人的生成式 AI 课程!我已偷偷学了起来
  • 原文地址:https://blog.csdn.net/qq_43448818/article/details/127071112