C++学习笔记24:多态案例之魔法门英雄无敌

需求分析:

    游戏:魔法门之英雄无敌
    游戏中有很多种怪物,每种怪物都有一个类与之对应,每个怪物就是一个对象
    类: CSoldier  CDragon  CPhonex  CAngel
    怪物能够互相攻击,攻击敌人和被攻击时都有相应的动作,动作是通过对象的成员函数实现。
    问题:游戏升级时,需要添加新的怪物--雷鸟,如何编程才能使得升级的时候代码改动和增加量较小  新增类:CThunderBird

基本思路:

    1 为每个怪物编写 Attack FightBack和Hurted成员函数
    2 Attack函数表示攻击动作,攻击某个怪物,并调用被攻击怪物的Hurted函数,以减少被攻击怪物的生命值,同时也调用被攻击怪物的FightBack成员函数,遭受被攻击怪物的反击
    3 Hurted函数减少自身生命值,并表现受伤动作
    4 FightBack成员函数表现反击动作,并调用被反击对象的Hurted成员函数,使得被反击对象受伤。
    5 设置基类CCreature,并且使得CDragon,CWolf等其他类都从CCreature派生而来

案例 非多态的实现方式(见本工程duotaishili.cpp)

//
// 非多态的实现方法
// 对于该程序,如果程序升级,增加了怪物雷鸟 CThunderBird,则程序变动较大

#include 

using namespace std;

class CCreature
{
protected:  //派生类的成员函数可以访问当前对象的基类的保护成员
    int nPower; // 代表攻击力
    int nLifeValue; // 代表生命值
};


/**
 * 问题:1 有n种怪物,CDragon类中就会有n个Attack成员函数,以及n个FightBack成员函数。对于其他类也是如此
 *      2 对于该程序,如果程序升级,增加了怪物雷鸟 CThunderBird,则程序变动较大
 *      3 所有的类都需要添加两个成员函数
 *          void Attack(CThunderBird* pThunderBird);
 *          void FightBack(CThunderBird* pThunderBird);
 *      4 在怪物种类多的时候,工作量非常大
 * */
class CDragon:public CCreature
{
public:
    void Attack(CWolf* pWolf)
    {
        // ... 表现攻击动作的代码
        pWolf->Hurted(nPower);
        pWolf->FightBack(this);
    }
    void Attack(CGhost* pGhost)
    {
        // ... 表现攻击动作的代码
        pGhost->Hurted(nPower);
        pGhost->FightBack(this);
    }
    void Hurted(int nPower)
    {
        // ... 表现受伤动作的代码
        nLifeValue -= nPower;
    }
    void FightBack(CWolf* pWolf)
    {
        // ... 表示反击动作的代码
        pWolf->Hurted(nPower/2);
    }
    void FightBack(CGhost* pGhost)
    {
        // ... 表示反击动作的代码
        pGhost->Hurted(nPower/2);
    }
};


int main()
{

}


7 案例 多态的实现方式(见本工程duotaishili2.cpp)

//
// 多态实现方式
// 基类只有一个Attack成员函数,也只有一个FightBack成员函数,所有CCreature的派生类也是这样。

#include 

using namespace std;

class CCreature
{
protected:
    int m_nLifeValue, m_nPower;
public:
    virtual void Attack(CCreature* pCreature){}
    virtual void Hurted(int nPower){}
    virtual void FightBack(CCreature* pCreature){}
};

/**
 * 优势:
 *      如果游戏版本升级,添加了新的怪物雷鸟CThunderBird
 *      只需要编写新类CThunderBird,不需要在已有的类里专门为新怪物添加
 *          void Attack(CThunderBird* pThunderBird);
 *          void FightBack(CThunderBird* pThunderBird);
 *      成员函数,已有的类可以原封不动,没压力啊!!
 */


// 派生类 CDragon
class CDragon:public CCreature
{
public:
    virtual void Attack(CCreature* pCreature);
    virtual void Hurted(int nPower);
    virtual void FightBack(CCreature* pCreature);
};

void CDragon::Attack(CCreature *pCreature) {
    // 表现攻击的代码
    pCreature->Hurted(m_nPower);    // 多态
    pCreature->FightBack(this);     // 多态
}

void CDragon::Hurted(int nPower) {
    // 表现受伤动作的代码
    m_nLifeValue -= nPower;
}

void CDragon::FightBack(CCreature *pCreature) {
    // 表现反击动作的代码
    pCreature->Hurted(m_nPower/2);  // 多态
}

int mian()
{

}


案例 多态的实现方式(见本工程duotaianli.cpp)

/**
 * 使用多态简单实现<魔法门游戏>
 */

#include 
#include "CCreature.h"
#include "CDragon.h"
#include "CGhost.h"
#include "CThunderBird.h"
#include "CWolf.h"

using namespace std;



int main()
{
    CDragon cDragon;
    CGhost cGhost;
    CThunderBird cThunderBird;
    CWolf cWolf;

    cDragon.Attack(&cWolf);     // 派生类对象的引用赋值给基类对象指针
    cDragon.Attack(&cGhost);
    cDragon.Attack(&cThunderBird);

    return 0;
}



你可能感兴趣的:(C++)