zoukankan      html  css  js  c++  java
  • C++多态原理

    C++的多态性是通过动态绑定实现的

    • 非虚函数是在编译时绑定的;
    • 通过对象进行的函数(虚函数,非虚函数)也是编译时绑定的;

    C++编译器在编译的时候,要确定每个对象调用的函数(要求此函数是非虚函数)的地址,这称为早期绑定(early binding)

    • 当且仅当通过指针或引用调用虚函数时,动态绑定

    动态绑定又叫运行时绑定(run time binding)。

    example:

    class animal{  
    public:  
        void sleep(){  cout<<"animal sleep"<<endl;  }  
        void breathe(){  cout<<"animal breathe"<<endl;  }  
    };  
    
    class fish:public animal{
    public:  
        void breathe(){  cout<<"fish bubble"<<endl;  }  
    };  
    
    int main(){  
        fish fh;  
        animal *pAn=&fh; // 隐式类型转换
        pAn->breathe();  // 运行结果: animal breathe
        return 0;
    }  
    

    因为编译器在编译的时候,就已经确定了对象调用的函数的地址
    pAn->breathe()的函数地址为animal::breathe()的地址。

    动态绑定

    要解决这个问题就要使用动态绑定技术(有的地方叫迟绑定(late binding)技术)。(c++是静态绑定语言,一些动态绑定语言 如java ,python)

    C++的多态性用一句话概括就是:

    1. 在基类的函数前加上virtual关键字,
    2. 在派生类中重写该函数,
    3. 运行时将会根据对象的实际类型来调用相应的函数。

    编译器在编译的时候,发现animal类中有虚函数,此时编译器会为每个包含虚函数的类创建一个虚表(即vtable),
    该表是一个一维数组,在这个数组 中存放每个虚函数的地址。
    对于例例子,animal和fish类都包含了一个虚函数breathe(),因此编译器会为这两个类都建立一个虚表。

    那么如何定位虚表呢?
    编译器另外还为每个类的对象提供了一个虚函数表指针(即vptr),这个指针指向了对象所属类的虚函数表。
    在程序运行时,根据对象的类型初始化vptr,从而让vptr正确的指向所属类的虚表,从而在调用虚函数时,就能够找到正确的函数。


    简而言之,多态性是一个接口多种实现。

  • 相关阅读:
    搭建一个简单的springMVC框架
    java枚举使用
    java中枚举类型的使用
    java递归算法
    JAVA递归算法及经典递归例子 对于这个汉诺塔问题
    java斐波纳契数列
    要求给一个数值,计算它的阶乘
    AcWing2193 分配问题(二分图最优匹配)
    2020上海大学校赛L 动物森友会(网络流+二分)
    BZOJ2654 tree(wqs二分)
  • 原文地址:https://www.cnblogs.com/iois/p/4979230.html
Copyright © 2011-2022 走看看