C++---day09

多态实例

#include<iostream>
using namespace std;


//战机
class HeroFighter
{
public:
    virtual int power()
    {
        return 10;
    }
protected:
private:
};

//敌机
class EnemyFighter
{
public:
    int attack()
    {
        return 15;
    }
protected:
private:
};

//升级战机
class AdvHeroFighter:public HeroFighter
{
public:
    virtual int power()
    {
        return 20;
    }
protected:
private:
};

//二次升级战机
class AdvAdvHeroFighter : public HeroFighter
{
public:
    virtual int power()
    {
        return 30;
    }
};


//多态威力
    //1 PlayObj给对象搭建舞台  看成一个框架
void PlayObj(HeroFighter *hf, EnemyFighter *ef)
{
    //不写virtual关键字 是静态联编 C++编译器根据HeroFighter类型,去执行 这个类型的power函数 在编译器编译阶段就已经决定了函数的调用
    //动态联编: 迟绑定:  //在运行的时候,根据具体对象(具体的类型),执行不同对象的函数 ,表现成多态.
    if (hf->power() > ef->attack())  //hf->power()函数调用会有多态发生
    {
        printf("主角win
");
    }
    else
    {
        printf("主角挂掉
");
    }
}

//多态的思想
//面向对象3大概念
//封装: 突破c函数的概念....用类做函数参数的时候,可以使用对象的属性 和对象的方法 
//继承: A B 代码复用
//多态 : 可以使用未来...


//多态很重要
//实现多态的三个条件
//C语言 间接赋值 是指针存在的最大意义
//是c语言的特有的现象 (1 定义两个变量  2 建立关联  3 *p在被调用函数中去间接的修改实参的值)

//实现多态的三个条件
//1 要有继承 
//2 要有虚函数重写
//3 用父类指针(父类引用)指向子类对象


void main()
{
    HeroFighter hf;
    AdvHeroFighter    Advhf;
    EnemyFighter    ef;
    AdvAdvHeroFighter advadvhf;

    PlayObj(&hf, &ef);
    PlayObj(&Advhf, &ef);
    PlayObj(&advadvhf, &ef) ; //这个框架 能把我们后来人写的代码,给调用起来

    system("pause");

}

void main1401()
{

    HeroFighter        hf;
    AdvHeroFighter    Advhf;
    EnemyFighter    ef;

    if (hf.power() > ef.attack())
    {
        printf("主角win
");
    }
    else
    {
        printf("主角挂掉
");
    }

    if (Advhf.power() > ef.attack())
    {
        printf("Adv 主角win
");
    }
    else
    {
        printf("Adv 主角挂掉
");
    }

    cout<<"hello..."<<endl;
    system("pause");
    return ;
}

多态是设计模式的基础,多态是框架的基础

重载和重写的理解

函数重载

    必须在同一个类中进行

    子类无法重载父类的函数,父类同名函数将被名称覆盖

函数重写

    必须发生于父类与子类之间

    并且父类与子类中的函数必须有完全相同的原型

    使用virtual声明之后能够产生多态(如果不用virtual,那叫重定义)

    多态是在运行期间根据具体对象的类型决定函数调用

#include <iostream>
using namespace std;

//重写 重载 重定义
//重写发生在2个类之间
//重载必须在一个类之间

//重写分为2类
//1. 虚函数重写  将发生多态
//2. 非虚函数重写 (重定义)

class Parent
{
    //这个三个函数都是重载关系
public: 
    void abc()
    {
        printf("abc");
    }

    virtual void func() 
    {
        cout<<"func() do..."<<endl;
    }
    virtual void func(int i)
    {
        cout<<"func() do..."<<i<<endl;
    }
    virtual void func(int i, int j)
    {
        cout<<"func() do..."<<i<< " "<<j<<endl;
    }

    virtual void func(int i, int j, int m , int n)
    {
        cout<<"func() do..."<<i<< " "<<j<<endl;
    }
protected:
private:
};


class Child : public Parent
{
    
public: 
    void abc()
    {
        printf("child abc");
    }
    /*
    void abc(int a)
    {
        printf("child abc");
    }
    */
    virtual void func(int i, int j)
    {
        cout<<"func(int i, int j) do..."<<i<< " "<<j<<endl;
    }
    virtual void func(int i, int j, int k)
    {
        cout<<"func(int i, int j) do.."<< endl; 
    }
protected:
private:
};


//重载重写和重定义
void main()
{
    //: error C2661: “Child::func”: 没有重载函数接受 0 个参数
    Child c1;
    //c1.abc();

    //c1.func();
    //子类无法重载父类的函数,父类同名函数将被名称覆盖
    //c1.Parent::func();

    //1 C++编译器 看到func名字 ,因子类中func名字已经存在了(名称覆盖).所以c++编译器不会去找父类的4个参数的func函数
    //2 c++编译器只会在子类中,查找func函数,找到了两个func,一个是2个参数的,一个是3个参数的.
    //3 C++编译器开始报错.....  error C2661: “Child::func”: 没有重载函数接受 4 个参数
    //4 若想调用父类的func,只能加上父类的域名..这样去调用..
    c1.func(1, 3, 4, 5);

    //c1.func();
    //func函数的名字,在子类中发生了名称覆盖;子类的函数的名字,占用了父类的函数的名字的位置
    //因为子类中已经有了func名字的重载形式。。。。
    //编译器开始在子类中找func函数。。。。但是没有0个参数的func函数 


    cout<<"hello..."<<endl;
    system("pause");
    return ;
}

解决方案

  • C++中通过virtual关键字对多态进行支持
  • 使用virtual声明的函数被重写后即可展现多态特性
原文地址:https://www.cnblogs.com/yangyuqing/p/10452084.html