• C++多态的实现机制


    1.静态联编与动态联编

       联编:是指一个程序模块、代码之间相互关联的过程

         静态联编(static binding):是程序的匹配、连接在编译阶段实现,重载函数使用静态联编

         动态联编:是指程序联编推迟到运行时进行,又称为迟联编。switch和if语句是动态联编的例子

    1.多态的实现机制

    1.用类定义对象的时候,如果类中包含有虚函数的话,C++编译器为每个对象编了一个一维的虚函数表(简称虚表)。这个虚函数表存储了类中虚函数的函数入口地址;

    2.用类定义对象的时候,如果类中包含有虚函数的话,C++编译器还为每个对象分配了一个指向虚表起始地址的指针vptr;

    3.当代码运行时,C++编译器首先判断父类指针调用的函数是不是虚函数。

    如果不是虚函数,则是普通函数。如果函数实参传的是父类对象的地址(或父类对象的引用),则父类指针调用父类对象中的普通函数;如果实参传的是子类对象的地址(或子类对象的引用),则父类指针调用子类中继承自父类的普通函数。

    如果是虚函数,则利用传递过来的实参的vptr指针找到虚表,根据虚表找到虚函数的入口地址,执行函数代码。这个过程C++编译器不需判断传来的实参是父类对象的地址(或引用)还是子类对象的地址(或引用),而是直接用传递过来的实参对象的vptr指针。

    以如下的代码为例:

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class Parent
     5 {
     6 public:
     7     Parent(int _a):a(_a){}
     8     ~Parent(){cout<<"执行Parent类析构函数"<<endl;}
     9     virtual void print(){cout<<"打印Parent类 a:"<<a<<endl;}
    10 
    11 public:
    12     int a;
    13 };
    14 
    15 
    16 class Child:public Parent
    17 {
    18 public:
    19     Child(int _a,int _a_,int _b):Parent(_a),a(_a_),b(_b){}
    20     ~Child(){cout<<"执行Child类析构函数"<<endl;}
    21     void print(){cout<<"打印Child类 b:"<<b<<endl;}
    22 
    23 public:
    24     int a;
    25     int b;
    26 };
    27 
    28 
    29 void fun(Parent* p)
    30 {
    31     p->print();
    32 }
    33 
    34 
    35 
    36 int main()
    37 {
    38     Parent p(5);
    39     Child  c(20,30,40);
    40 
    41     fun(&p);
    42     fun(&c);
    43     
    44     return 0;
    45 }

    代码的执行结果为:

    打印Parent类 a:5

    打印Child类 b:40

    执行Child类析构函数

    执行Parent类析构函数

    执行Parent类析构函数

    关于vptr指针的几点说明:

    1.代码中的fun()函数调用的print()函数是虚函数,则走的是vptr-->虚表-->虚函数代码这条路线。C++编译器执行fun()函数时,不需要区分是子类对象还是父类对象;

    2.初始化子类Child的对象c时,c.vptr的初始化是分步进行的:当执行父类的构造函数时,c.vptr指向父类的虚函数表,当父类的构造函数执行完毕后,会把c.vptr指向子类的虚函数表;

    3.通过虚函数表指针vptr调用重写函数是在程序运行时进行的,因此需要通过寻址操作才能确定真正应该调用的函数。而普通成员函数是在编译时就确定了调用的函数。在效率上,虚函数的效率要低很多。因此,出于效率考虑,没有必要将所有成员函数都声明为虚函数;

    对多态的理解:

    多态的实现效果:同样的调用语句有多种不同的表现形态;

    多态实现的3个条件:a.要有继承  b.有virtual重写  c.有父类指针(引用)指向子类对象;

    多态的C++实现:virtual关键字,告诉编译器这个函数要支持多态,不是根据指针类型决定函数调用,而是要根据指针所指向的实际对象类型来决定函数调用;

    多态的理论基础:静态联编PK动态联编,根据实际对象的类型来判断重写函数的调用;

    多态的重要意义:设计模式的基础,框架的基石;

    实现多态的理论基础:函数指针做函数参数;

    多态的实现原理:C++编译器提前布局了一个vptr指针,利用vptr指针找到虚函数表,进而找到函数的入口地址,进行动态的迟绑定

  • 相关阅读:
    mysql 大数据量求平均值
    mysql 大数据量求平均值
    dhcpd.conf(5)
    dhcpd.conf(5)
    学习记录(文章内容来自相关材料)
    分享一个ASP.NET 文件压缩解压类 C#
    服务降级
    distinct用法
    trim合理和谐
    小娱乐一下,fileInfo中的Name ,FullName的用法小BUG
  • 原文地址:https://www.cnblogs.com/jswu-ustc/p/8393743.html
Copyright © 2020-2023  润新知