zoukankan      html  css  js  c++  java
  • 虚函数

    看这样一个例子:
    先定义一个类(人类),类里有一个成员函数:人有俩眼睛

    class Human
    {
    private:
        /* data */
    public:
        Human(/* args */);
        ~Human();
        void eyes();
    };
    
    Human::Human(/* args */)
    {
    }
    
    Human::~Human()
    {
    }
    
    void Human::eyes()
    {
        cout<<"human have two eyes"<<endl;
    }

    再用这个类派生一个子类:杨戬,那很显然,杨戬有三只眼睛

    class YangJian:public Human
    {
    private:
        /* data */
    public:
        YangJian(/* args */);
        ~YangJian();
        void eyes();
    };
    
    YangJian::YangJian(/* args */)
    {
    }
    
    YangJian::~YangJian()
    {
    }
    
    void YangJian::eyes()
    {
        cout<<"YangJian have three eyes"<<endl;
    }

    在主函数中分别调用这两个类的函数

    int main(int argc, char const *argv[])
    {
        Human xiaoming;
        xiaoming.eyes();
        YangJian yangjian;
        yangjian.eyes();
    }

    输出结果很美好

    human have two eyes
    YangJian have three eyes

    人有俩眼睛,杨戬有仨。

    没有任何问题。

    现在我要在一个函数中调用这个eyes

    void eyescount(Human &p)
    {
        p.eyes();
    }

    接下来在主函数中分别对两个对象调用这个函数

    int main(int argc, char const *argv[])
    {
        Human xiaoming;
        xiaoming.eyes();
        YangJian yangjian;
        yangjian.eyes();
    
        eyescount(xiaoming);
        eyescount(yangjian);
    }

    讲道理,输出结果应该和前面一样。小明俩眼睛,杨戬仨眼睛

    但是实际上的输出:

    human have two eyes
    YangJian have three eyes
    human have two eyes
    human have two eyes

    问题出现了!

    我传入的是YangJian这个对象的参数,但是进入函数之后调用的却是他的父类Human的函数。

    也就是说,只有我这个函数写成这个样子,它才肯调用YangJian 的 eyes()

    void eyescount(YangJian &p)
    {
        p.eyes();
    }

    那我Human有各种子类,除了杨戬,

    我还有独眼的夏侯惇,还有仨眼睛的马王爷,还有三头六臂六个眼睛的哪吒,再带上几个千手千眼的菩萨。那我这个函数得重载多少次

    那么为了解决这样的问题,就有了虚函数这样一个概念。

    现在回到最开始定义Human的成员函数里面

    class Human
    {
    private:
        /* data */
    public:
        Human(/* args */);
        ~Human();
        virtual void eyes();
    };

    我们在父类函数声明之前,加一个virtual关键字,也就是本文的虚函数

    其他地方没有任何改动,再运行一遍这个程序。

    human have two eyes
    YangJian have three eyes
    human have two eyes
    YangJian have three eyes

    这样打印出来的结果就回归正常了

    有了虚函数,基类指针指向基类对象时就使用基类的成员(包括成员函数和成员变量),指向派生类对象时就使用派生类的成员。换句话说,基类指针可以按照基类的方式来做事,也可以按照派生类的方式来做事,它有多种形态,或者说有多种表现方式,我们将这种现象称为多态(Polymorphism)。

  • 相关阅读:
    微信小程序(三)-事件绑定
    微信小程序(二)-语法学习
    微信小程序(一)-工具创建和结构配置说明 Stable Build
    ============================================ 微信小程序开发学习
    Vue学习笔记-Vue.js-2.X 学习(七)===>脚手架Vue-CLI(路由Router)
    Vue学习笔记-Vue.js-2.X 学习(六)===>脚手架Vue-CLI(项目说明-Babel)
    Vue学习笔记-Vue.js-2.X 学习(五)===>脚手架Vue-CLI(PyCharm)
    linux打包压缩命令汇总
    js中函数之函数名带括号与不带括号的区别
    $_FILES error(笔记)
  • 原文地址:https://www.cnblogs.com/qifeng1024/p/12641989.html
Copyright © 2011-2022 走看看