多态(动态多态)与重载(静态多态)
问题描述:
假设要设计一款游戏,里面有许多怪物,当新增怪物的时候,下面列举不采用多态和采用多态时的区别。
- 不采用多态
class Creature
{
protected:
int Power; //攻击力
int Life; //生命值
}
class Dragon: public Creature
{
public:
void Hurted(int AttackLife)
{
Power -= AttackLife;
}
void attack(Wolf* pWolf, int nPower)
{
cout << "狼被攻击" << endl;
pWolf->Hurted(nPower);
}
void attack(Sheep* pSheep, int nPower)
{
cout << "羊被攻击" << endl;
pSheep->Hurted(nPower);
}
}
class Wolf: public Creature
{
public:
void Hurted(int AttackLife)
{
Power -= AttackLife;
}
void attack(Dragon* pDragon, int nPower)
{
cout << "龙被攻击" << endl;
pDragon->Hurted(nPower);
}
void attack(Sheep* pSheep, int nPower)
{
cout << "羊被攻击" << endl;
pSheep->Hurted(nPower);
}
}
class Sheep:public Creature
{
//...后面省略
}
- 采用多态
class Creature
{
protected:
int Power;
int Life;
}
class Dragon: public Creature
{
virtual void Hurted(int AttackLife)
{
Power -= AttackLife;
}
virtual void attack(Creature* pCreature, int nPower)
{
pCreature->Hurted(nPower);
}
}
class Wolf: public Creature
{
virtual void Hurted(int AttackLife)
{
Power -= AttackLife;
}
virtual void attack(Creature* pCreature, int nPower)
{
pCreature->Hurted(nPower);
}
}
class Sheep: public Creature
{
virtual void Hurted(int AttackLife)
{
Power -= AttackLife;
}
virtual void attack(Creature* pCreature, int nPower)
{
pCreature->Hurted(nPower);
}
}
可以发现,当要新增“怪物”时候,每一个原来定义好的“怪物”都要新增一个attack()
函数,大大降低了代码的复用性。而如果采用多态,则只需要写一个新增的“怪物”类即可,大大增加了代码的复用性。
Note:里面的虚函数不用在意是什么意思,只是作为多态的使用而特殊定义的函数,其用法和一般的方法类一致。
其他:
1、上面说的多态(动态多态)与重载(静态多态)不同,多态在运行时检测要调用的(虚)函数,重载在编译时检测要调用的函数;
2、在运行时检测的类型成为动态类型,在编译时检测的类型成为静态类型;
3、动态虽然提高了代码的复用性,但是却额外消耗了空间和时间。e. g.
class Base
{
public:
int i; //4字节
virtual void Print{cout <<"Base::Print"<<endl;}
}
class Derived: public Base
{
public:
int n; //4字节
virtual void Print{cout <<"Derive::Print"<<endl;}
}
int main()
{
Base b;
Derive d;
sizeof(b); //8(字节)
sizeof(d); //12(字节)
return 0;
}
原因:
每一个含有虚函数的类都包含一个存储虚函数表地址的空间,用以调用虚函数。