zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    通过web端启动关闭服务器程序以及检测程序运行状态
    Windows 自动监听程序,游戏服务器挂掉以后,自动监听程序将其重启起来
    自动监听程序,如果程序挂了,就重启
    删除log
    封装了一个C++类,当程序意外崩溃的时候可以生成dump文件,以便确定错误原因。
    贝塞尔曲线
    golang sql连接池 超时 数据库自动断开 ->127.0.0.1:3 306: wsarecv: An established connection was aborted by the software in your host machine.
    带控制的抢庄牛牛
    龙虎斗控制
    回归模型与房价预测
  • 原文地址:https://www.cnblogs.com/xiaobaizzz/p/12335080.html
Copyright © 2011-2022 走看看