class CDragon
{
private:
int power; //攻击力
int lifeValue; //生命值
public:
void Attack(CWolf * p); //攻击“狼”的成员函数
void Attack(CGhost* p); //攻击“鬼”的成员函数
//……其他 Attack 重载函数
//表现受伤的成员函数
void Hurted(int nPower);
void FightBack(CWolf * p); //反击“狼”的成员函数
void FightBack(CGhost* p); //反击“鬼”的成员函数
//......其他FightBack重载函数
};
各成员函数的写法如下:
void CDragon::Attack(CWolf* p)
{
p->Hurted(power);
p->FightBack(this);
}
void CDragon::Attack(CGhost* p)
{
p->Hurted(power);
p->FightBack(this);
}
void CDragon::Hurted(int nPower)
{
lifeValue -= nPower;
}
void CDragon::FightBack(CWolf* p)
{
p->Hurted(power / 2);
}
void CDragon::FightBack(CGhost* p)
{
p->Hurted(power / 2);
}
第 1 行,Attack 函数的参数 p 指向被攻击的 CWolf 对象。void Attack(CThunderBird* p); void FightBack(CThunderBird* p);这样,在怪物种类多的时候,工作量会比较大。
class CCreature { //“怪物”类
protected:
int lifeValue, power;
public:
virtual void Attack(CCreature* p) {};
virtual void Hurted(int nPower) {};
virtual void FightBack(CCreature* p) {};
};
可以看到,基类 CCreature 中只有一个 Attack 成员函数,也只有一个 FightBack 成员函数。
class CDragon : public CCreature
{
public:
virtual void Attack(CCreature* p) {
p->Hurted(power);
p->FightBack(this);
}
virtual int Hurted(int nPower) {
lifeValue -= nPower;
}
virtual int FightBack(CCreature* p) {
p->Hurted(power / 2);
}
};
CDragon 类的成员函数中省略了表现动作和声音的那部分代码。其他类的写法和 CDragon 类类似,只是实现动作和声音的代码不同。如何实现动画的动作和声音不是本书要讲述的内容。CDragon dragon; CWolf wolf; CGhost ghost; CThunderBird bird; Dragon.Attack(&wolf); Dragon.Attack(&ghost); Dragon.Attack(&bird);根据赋值兼容规则,上面第 5、6、7 行中的参数都与基类指针类型 CCreature* 相匹配,所以编译没有问题。从 5、6、7 三行进入 CDragon::Attack 函数后,执行 p-> Hurted(power) 语句时,p 分别指向的是 wolf、ghost 和 bird,根据多态的规则,分别调用的就是 CWolf::Hurted、CGhost::Hurted 和 CBird: Hurted 函数。
#include <iostream>
#include <cmath>
using namespace std;
class CShape //基类:形体类
{
public:
virtual double Area() { }; //求面积
virtual void PrintInfo() { }; //显示信息
};
class CRectangle:public CShape //派生类:矩形类
{
public:
int w,h; //宽和高
virtual double Area();
virtual void PrintInfo();
};
class CCircle:public CShape //派生类:圆类
{
public:
int r; //半径
virtual double Area();
virtual void PrintInfo();
};
class CTriangle:public CShape //派生类:三角形类
{
public:
int a,b,c; //三边长
virtual double Area();
virtual void PrintInfo();
};
double CRectangle::Area() {
return w * h;
}
void CRectangle::PrintInfo() {
cout << "Rectangle:" << Area() << endl;
}
double CCircle::Area() {
return 3.14 * r * r ;
}
void CCircle::PrintInfo() {
cout << "Circle:" << Area() << endl;
}
double CTriangle::Area() { //根据海伦公式计算三角形面积
double p = ( a + b + c) / 2.0;
return sqrt(p * ( p - a)*(p- b)*(p - c));
}
void CTriangle::PrintInfo() {
cout << "Triangle:" << Area() << endl;
}
CShape *pShapes[100]; //用来存放各种几何形体,假设不超过100个
int MyCompare(const void *s1, const void *s2) //定义排序规则的函数
{
CShape **p1 = (CShape **)s1; //s1是指向指针的指针,其指向的指针为CShape* 类型
CShape **p2 = ( CShape **)s2;
double a1 = (*p1)->Area(); //p1指向几何形体对象的指针, *p1才指向几何形体对象
double a2 = (*p2)->Area();
if( a1 < a2 )
return -1; //面积小的排前面
else if (a2 < a1)
return 1;
else
return 0;
}
int main()
{
int i; int n;
CRectangle *pr; CCircle *pc; CTriangle *pt;
cin >> n;
for( i = 0;i < n;++i ) {
char c;
cin >> c;
switch(c) {
case 'R': //矩形
pr = new CRectangle();
cin >> pr->w >> pr->h;
pShapes[i] = pr;
break;
case 'C': //圆
pc = new CCircle();
cin >> pc->r;
pShapes[i] = pc;
break;
case 'T': //三角形
pt = new CTriangle();
cin >> pt->a >> pt->b >> pt->c;
pShapes[i] = pt;
break;
}
}
qsort(pShapes,n,sizeof(Cshape *),MyCompare);
for(i = 0;i <n;++i) {
pShapes[i]->PrintInfo();
delete pShapes[i]; //释放空间
}
return 0;
}
程序涉及三种几何形体。如果不使用多态,就需要用三个数组分别存放三种几何形体,不但编码麻烦,而且如果以后要增加新的几何形体,就要增加新的数组,扩充性不好。(*p1)->Area()就能求该对象的面积了(第 55 行)。(* p1) -> Area();这条语句是多态的,因为 *p1 是基类指针,Area 是虚函数。程序运行到此时,*p1 指向哪种对象,就会调用相应类的计算面积函数 Area,正确求得其面积。
版权说明:Copyright © 广州松河信息科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州松河信息科技有限公司 版权所有