中國大學MOOC程序設計與算法(三):C++ 面向對象程序設計 第六週 多態 筆記 之 多態實例:魔法門之英雄無敵

第六週 多態
1.虛函數和多態的基本概念
2.多態實例:魔法門之英雄無敵
3.更多多態程序實例
4.多態的實現原理
5.虛析構函數、純虛函數和抽象類

2.多態實例:魔法門之英雄無敵

遊戲中有很多種怪物,每種怪物都有一個類與之對應,每個怪物就是一個對象。假設現在有五種怪物,也就是現有五個類:CSoldier,CDragon,Cwolf,CPhonex,CAngel。怪物能夠互相攻擊,攻擊敵人和被攻擊時都有相應的動作,動作是通過對象的成員函數實現的。遊戲版本升級時,要增加新的怪物–雷鳥類CThunderBird。如何編程才能使升級時的代碼改動和增加量較小?

基本思路:

爲每個怪物類編寫 Attack、FightBack和 Hurted成員函數。
Attact函數表現攻擊動作,攻擊某個怪物,並調用被攻擊怪物的Hurted函數,以減少被攻擊怪物的生命值,同時也調用被攻擊怪物的 FightBack成員函數,遭受被攻擊怪物反擊。
Hurted函數減少自身生命值,並表現受傷動作。
FightBack成員函數表現反擊動作,並調用被反擊對象的Hurted成員函數,使被反擊對象受傷。
設置基類 CCreature,並且使CDragon, CWolf等其他類都從CCreature派生而來。
在這裏插入圖片描述

非多態的實現方法

class class CCreature {
	protected:  
		int nPower ; //代表攻擊力
		int nLifeValue ; //代表生命值
};
class CDragon:public CCreature {
	public:
		void Attack(CWolf * pWolf) {
			//表現攻擊動作的代碼
			pWolf->Hurted( nPower);
			pWolf->FightBack( this);
		}
		void Attack( CGhost * pGhost) {
			//表現攻擊動作的代碼
			pGhost->Hurted( nPower);
			pGohst->FightBack( this);
		}
		void Hurted ( int nPower) {
			//表現受傷動作的代碼
			nLifeValue -= nPower;
		}
		void FightBack( CWolf * pWolf) {
			//表現反擊動作的代碼
			pWolf ->Hurted( nPower / 2);
		}
		void FightBack( CGhost * pGhost) {
			//表現反擊動作的代碼
			pGhost->Hurted( nPower / 2 );
		}
}

有n種怪物,CDragon 類中就會有n個 Attack 成員函數,以及 n個FightBack成員函數。對於其他類也如此。
缺點: 如果遊戲版本升級,增加了新的怪物雷鳥 CThunderBird,則程序改動較大。所有的類都需要增加兩個成員函數:
void Attack( CThunderBird * pThunderBird)和void FightBack( CThunderBird * pThunderBird) ,工作量極大。

多態的實現方法

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

基類只有一個 Attack 成員函數;也只有一個 FightBack成員函數;所有CCreature 的派生類也是這樣。

// 以派生類 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 * p)
{ 
	//表現攻擊動作的代碼
	p->Hurted(m_nPower); //多態
	p->FightBack(this); //多態
}
void CDragon::Hurted( int nPower)
{ 
	//表現受傷動作的代碼
	m_nLifeValue -= nPower;
}
void CDragon::FightBack(CCreature * p)
{
	//表現反擊動作的代碼
	p->Hurted(m_nPower/2); //多態
}  

優勢:如果遊戲版本升級,增加了新的怪物雷鳥 CThunderBird,只需要編寫新類CThunderBird, 不需要在已有的類裏專
門爲新怪物增加void Attack( CThunderBird * pThunderBird) 和void FightBack( CThunderBird * pThunderBird) ,成員函數,已有的類可以原封不動。

原理

CDragon Dragon; CWolf Wolf; CGhost Ghost;
CThunderBird Bird;
Dragon.Attack( & Wolf);  //(1)
Dragon.Attack( & Ghost); //(2)
Dragon.Attack( & Bird); //(3)

根據多態的規則,上面的(1),(2),(3)進入到CDragon::Attack函數後,能分別調用:

CWolf::Hurted
CGhost::Hurted
CBird::Hurted
void CDragon::Attack(CCreature * p)
{
	p->Hurted(m_nPower); //多態
	p->FightBack(this); //多態
}

發佈了53 篇原創文章 · 獲贊 4 · 訪問量 2008
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章