C++ 虚函数表

  • 当通过指针访问类的成员函数时:

    • 如果该函数是非虚函数:编译器会根据指针的类型找到该函数。
    • 如果该函数是虚函数,并且派生类有同名的函数遮蔽它:编译器会根据指针的指向找到该函数,这就是多态。
  • 对象的内存模型是非常干净的,没有包含任何成员函数的信息,编译器究竟是根据什么找到了成员函数呢?

    • 编译器之所以能通过指针指向的对象找到虚函数,是因为在创建对象时额外的增加了虚函数表
  • 虚函数表(vtable)

    • 如果一个类包含了虚函数,那么在创建该类的对象时就会额外的增加一个数组,数组中每一个元素都是虚函数的入口地址。
    • 不过数组和对象是分开存储的,为了将对象和数组关联起来,编译器还要再对象中安插一个指针,指向数组的起始位置。
    • 这里的数组就是虚函数表。
    #include <iostream>
    #include <string>
    using namespace std;
    
    //People类
    class People{
    public:
        People(string name, int age); //构造函数 
    public:
        virtual void display();
        virtual void eating();
    protected:
        string m_name;
        int m_age;
    };
    People::People(string name, int age): m_name(name), m_age(age){ }
    void People::display(){
        cout<<"Class People:"<<m_name<<"今年"<<m_age<<"岁了。"<<endl;
    }
    void People::eating(){
        cout<<"Class People:我正在吃饭,请不要跟我说话..."<<endl;
    }
    
    //Student类
    class Student: public People{
    public:
        Student(string name, int age, float score); //构造函数 
    public:
        virtual void display();
        virtual void examing();
    protected:
        float m_score;
    };
    Student::Student(string name, int age, float score):
        People(name, age), m_score(score){ }
    void Student::display(){
        cout<<"Class Student:"<<m_name<<"今年"<<m_age<<"岁了,考了"<<m_score<<"分。"<<endl;
    }
    void Student::examing(){
        cout<<"Class Student:"<<m_name<<"正在考试,请不要打扰T啊!"<<endl;
    }
    
    //Senior类
    class Senior: public Student{
    public:
        Senior(string name, int age, float score, bool hasJob); //构造函数 
    public:
        virtual void display();
        virtual void partying();
    private:
        bool m_hasJob;
    };
    Senior::Senior(string name, int age, float score, bool hasJob):
        Student(name, age, score), m_hasJob(hasJob){ }
    void Senior::display(){
        if(m_hasJob){
            cout<<"Class Senior:"<<m_name<<"以"<<m_score<<"的成绩从大学毕业了,并且顺利找到了工作,Ta今年"<<m_age<<"岁。"<<endl;
        }else{
            cout<<"Class Senior:"<<m_name<<"以"<<m_score<<"的成绩从大学毕业了,不过找工作不顺利,Ta今年"<<m_age<<"岁。"<<endl;
        }
    }
    void Senior::partying(){
        cout<<"Class Senior:快毕业了,大家都在吃散伙饭..."<<endl;
    }
    
    int main(){
        People *p = new People("赵红", 29); //基类指针指向基类 
        p -> display();
    
        p = new Student("王刚", 16, 84.5); //基类指针指向派生类 
        p -> display();
    
        p = new Senior("李智", 22, 92.0, true); //基类指针指向派生类 
        p -> display();
    
        return 0;
    }
    
    /*运行结果:*/
    Class People:赵红今年29岁了。
    Class Student:王刚今年16岁了,考了84.5分。
    Class Senior:李智以92的成绩从大学毕业了,并且顺利找到了工作,Ta今年22岁。
    

    image

原文链接: https://www.cnblogs.com/xiaobaizzz/p/12335080.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++ 虚函数表

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/330617

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月1日 下午5:40
下一篇 2023年3月1日 下午5:40

相关推荐