zoukankan      html  css  js  c++  java
  • 多态(1)—— 多态的定义、多态的三个必要条件、静态联编和动态联编、虚析构函数、重载重写重定义

    1、多态的意义

      如果有几个上似而不完全相同的对象,有时人们要求在向它们发出同一个消息时, 它们的反应各不相同,分别执行不同的操作。这种情况就是多态现象。

      C++中所谓的多态(polymorphism)是指,由继承而产生的相关的不同的类,其对象对同一消息会作出不同的响应。

    2、多态的三个必要条件

    • 要有继承
    • 要有虚函数重写
    • 要有父类指针(父类引用)指向子类对象
    #include <iostream>
    #include <string>
    using namespace std;
    
    class Yuebuqun
    {
    public:
        Yuebuqun(string kongfu)
        {
            this->kongfu = kongfu;
        }
        virtual void fight()//表示修饰一个成员方法是一个虚函数,必要条件2
        {
            cout << "岳不群" << "使用了" << this->kongfu << endl;
        }
    
        string kongfu;
    };
    
    //林平之继承了岳不群
    class Linpingzhi :public Yuebuqun
    {
    public:
        Linpingzhi(string kongfu) :Yuebuqun(kongfu)
        {
        }
    
        //如果说父类中有一个虚函数是fight(),子类如果去重写这个虚函数,
        //那么如果传递进来的是子类,调用子类的fight,如果传递进来的是父类,调用父类的fight
        void fight()//必要条件2
        {
            cout << "林平之" << "使用了" << kongfu << endl;
        }
    };
    
    //令狐冲继承了岳不群
    class Linghuchong :public Yuebuqun
    {
    public:
        Linghuchong(string kongfu) :Yuebuqun(kongfu)
        {
        }
    
        void fight()
        {
            cout << "令狐冲" << "使用了" << kongfu << endl;
        }
    };
    
    //在全局提供一个打斗的方法
    void fightPeople(Yuebuqun *hero)//必要条件3,相当于Yuebuqun *hero = xiaopp;或Yuebuqun *hero = xiaoyy;
                                    //或Yuebuqun *hero = xiaoll;
    {
        hero->fight();//希望如果传递进来的是子类,调用子类的fight;
                      //如果传递进来的是父类,调用父类的fight
                      //这种行为就是多态行为
    }
    
    //多态发生的三个必要条件:
    //1.要有继承
    //2.要有虚函数重写
    //3.父类指针或引用指向子类对象
    int main(void)
    {
        Yuebuqun *xiaoyy = new Yuebuqun("葵花宝典");
        xiaoyy->fight();
    
        Linpingzhi *xiaopp = new Linpingzhi("辟邪剑谱");
        xiaopp->fight();
    
        Linghuchong *xiaoll = new Linghuchong("独孤九剑");
        xiaoll->fight();
    
        //多态的实现
        fightPeople(xiaoyy);//岳不群使用了葵花宝典
        fightPeople(xiaopp);//林平之使用了辟邪剑谱
        fightPeople(xiaoll);//令狐冲使用了独孤九剑
        //编译器默认做了一个安全的处理,编译认为不管传递时子类对象还是父类对象,
        //如果统一执行父类的方法,那么一定可以被成功执行。
    
        delete xiaoyy;
        delete xiaopp;
        delete xiaoll;
    
        return 0;
    }

     3、静态联编和动态联编

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

    (2)静态联编,是程序的匹配、连接在编译阶段实现,也称为早期匹配。重载函数使用静态联编。

    (3)动态联编是指程序联编推迟到运行时进行,所以又称为晚期联编(迟邦定)。switch语句和if语句是动态联编的例子。

    1、C++与C相同,是静态编译型语言;
    2、在编译时,编译器自动根据指针的类型判断指向的是一个什么样的对象;所以编译器认为父类指针指向的是父类对象;
    3、由于程序没有运行,所以不可能知道父类指针指向的具体是父类对象还是子类对象,从程序安全的角度,编译器假设父类指针只指向父类对象,因此编译的结果为调用父类的成员函数。这种特性就是静态联编;
    4、多态的发生是动态联编,实在程序执行的时候判断具体父类指针应该调用的方法。

     4、虚析构函数

    • 构造函数不能是虚函数。建立一个派生类对象时,必须从类层次的根开始,沿着继承路径逐个调用基类的构造函数。
    • 析构函数可以是虚的。虚析构函数用于指引delete运算符正确析构动态对象。

    5、重载重写重定义

    重载(添加)
    a、相同的范围(在同一个类中)
    b、函数名字相同
    c、参数不同
    d、virtual可有可无
    重写(覆盖) 是指派生类函数覆盖基类函数,特征是:
    a、不同的范围,分别位于基类和派生类中
    b、函数名字相同
    c、参数相同
    d、基类函数必须有virtual关键字
    重定义(隐藏) 是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
    a、如果派生类的函数和基类的函数同名,但是参数不同,此时,不管有无virtual,基类的函数被隐藏。
    b、如果派生类的函数与基类的函数同名,但是参数也相同,但是基类函数没有virtual关键字,此时,基类的函数被隐藏。
  • 相关阅读:
    世界企业家:创业者需知的8条创业逻辑
    比尔·盖茨的“机会”观——不追求机会,才会有机会
    我爱思佳(帮别人名字作诗)
    唐艺铭(帮别人名字作诗)
    我爱思佳(帮别人名字再作诗)
    优秀是一种习惯:智者五句话足以改变你的人生
    别了,我的情人
    李丽萍(帮别人名字作诗)
    Know GCS AND GES structure size in shared pool
    测试Exadata单个cell失败
  • 原文地址:https://www.cnblogs.com/yuehouse/p/9845373.html
Copyright © 2011-2022 走看看