zoukankan      html  css  js  c++  java
  • 多态实现--虚函数与纯虚函数

    多态实现--虚函数与纯虚函数

    • C++中实现多态是使用虚函数表的方法实现的。
    • 那么具体怎么实现的呢?

    举例说明

    • 假设有这样一个多态场景:
    • 有一个基类动物(animal类),动物里面又有两个派生类:猫(cat类)和狗(dog类)。现在要求动物类有一个共同的方法:叫声(voice成员函数),但猫和狗叫声是不同的(即:它们的叫声实现方法不同)。
    • 那么代码怎么写呢?

    多态的代码实现

    #include <iostream>
    using namespace std;
    
    //1、 定义一个带纯虚函数的抽象类作为基类
    class animal
    {
    public:
        virtual void voice()= 0;    //纯虚函数voice
    };
    
    //2、 定义猫(cat)狗(dog)类,共同继承自animal,但对voice进行了具体实现
    class cat:public animal
    {
    public:
        virtual void voice()
        {
            cout <<"喵喵喵"<<endl;
        }
    };
    
    class dog:public animal
    {
    public:
        virtual void voice()
        {
            cout <<"汪汪汪"<<endl;
        }
    };
    
    //3、那么下一步就要给猫和狗做一个统一接口了,传参用基类指针。这个接口只有一个功能,就是调用动物叫声voice。
    void animal_voice(animal * a)
    {
        a->voice();
    }
    
    //4、 多态写好了,我们来调用一下试试,写个test看看这个多态有没有问题。我们分别定义一个猫狗对象,来调用统一接口,看看它们的叫声是否相同。
    
    void test()
    {
        cat c;
        dog d;
        animal_voice(&c);
        animal_voice(&d);
    }
    
    int main()
    {
        test();
        return 0;
    }
    
    • 验证结果:
    喵喵喵
    汪汪汪
    

    说明这个多态已实现完成。

    多态原理

    • 那么多态的原理是怎么样的呢?为什么这样写代码,就能实现猫和狗叫声不同,它们明明调用的是同一个接口呀?

    • 实际上这个例子的程序运行时,为cat和dog分别生成了一张虚函数表,将函数地址记录在各自的虚函数表中。如图所示。

      • cat的虚函数表:
      cat的虚函数表
      cat的voice函数的地址
      • dog的虚函数表:
      dog的虚函数表
      dog的voice函数的地址
    • 这样当我们用接口调用cat和dog的voice函数时,它们会各自在自己的虚函数表里寻找,找到自己的voice函数地址,根据这个地址来进行调用。怎么样,多态实现原理也很简单吧?

    虚函数与纯虚函数

    • 那么animal里的纯虚函数“virtual void voice()= 0;”只能这样写吗?它可以像下面这样写成虚函数吗?
    virtual void voice()
    {
    
    }
    
    • 答案是可以,但它们是不同的。写成虚函数,说明是有实现的(animal也因此变得不再是抽象类),只是它的实现方法是空,那么在cat和dog中我们再次实现这个voice时,就自动将基类的该voice方法重写(override)了(也就是说,我们也可以选择省略(即:不override)这个voice)。但如果写成纯虚函数,那么我们就必须要在cat和dog中具体实现voice,才能使用voice,否则cat和dog也和animal一样是抽象类,不能用来实例化对象。

    • 也就是虚函数是有这个函数的实现,而纯虚函数是这个函数根本还没实现。

    • 再补一个小知识:如果基类的voice写成虚函数,而不是纯虚函数话,派生类即使将其override了,还是可以通过作用域的方法来访问的(实际上override时,基类的voice方法只是被默认隐藏了)。

  • 相关阅读:
    SAP PI 如何实现消息定义查询
    EWM与ERP交互程序
    ITS Mobile Template interpretation failed. Template does not exist
    SAP Material Flow System (MFS) 物料流系统简介
    SAP EWM Table list
    EWM RF 屏幕增强
    SAP EWM TCODE list
    SAP扩展仓库管理(SAPEWM)在线研讨会笔记
    ERP与EWM集成配置ERP端组织架构(二)
    EWM RF(Radio Frequency)简介
  • 原文地址:https://www.cnblogs.com/linkyip/p/8414358.html
Copyright © 2011-2022 走看看