首先我们得清楚,继承则子类包含父类的所有数据和函数,只是有些函数可能会被overwrite或override。
然后含有纯虚函数的抽象类不能被实例化,但是它的子类能够实例化(子类定义了此纯虚函数),并且父类的其他函数仍然包含非抽象类的函数应该包含的性质。
class A{
public:
void func() {cout<<1;}
}
class B:public A{
}
B b;
B *p=&b;
p->func();
A *pa=p;
pa->func();
目录
基本思路:
纯虚函数的缺省定义:
编程例子:
①怪兽PK(基本子类)
②饮料加配料(子类代替名字,抽象出来)
基本思路:
①父类的析构函数应当为虚的
②父类作为各种子类的共有部分,它应当包含子类所具有的全部共同数据和函数。
③子类各部分自定义实现的函数,父类应当定义为虚函数,并且若父类是实例化无意义的类,可以将此函数定义为纯虚函数=0(父类没必要一定是接口类,也可以是抽象类)
④可以给子类传参,构造父类所含的共有部分。
⑤记住,父类的函数和数据,子类只要不重名,子类可以直接使用。
⑥父类的共有数据部分,如果子类需要直接调用可以定义为protected访问控制
⑦若子类都必须拥有一个共有行为,那么就可以定义一个纯虚函数=0,纯虚函数的存在,要求子类必须自己定义这个函数(若不自行定义,子类仍然是个抽象类),可以选择利用父类原有的缺省定义,也可以选择自己定义。
纯虚函数的缺省定义:
父类纯虚函数的声明只是提供一个共有的接口,而它的缺省定义 只是给 子类用的一个默认方法,对于它是纯虚函数以及父类不可实例化这个事实并没有做出任何改变,也就是不对父类产生影响。但是子类就可以 选择它的默认方法了,也可以选择自己重新定义
class B{
public:
virtual ~B() {cout<<"B";};
virtual void fun() =0;
};
void B::fun() {cout<<1;}//缺省定义
class A:public B{
public:
~A() {cout<<"A";};
void fun() { B::fun();}//子类必须重新定义,选择默认必须用基类class名加::使用。
};
编程例子:
①怪兽PK(基本子类)
①父类的析构函数应当为虚的
②父类作为各种子类的共有部分,它应当包含子类所具有的全部共同数据和函数。
③子类各部分自定义实现的函数,父类应当定义为虚函数,并且若父类是实例化无意义的类,可以将此函数定义为纯虚函数=0(父类没必要一定是接口类,也可以是抽象类)
④可以给子类传参,构造父类所含的共有部分。
⑤记住,父类的函数和数据,子类只要不重名,子类可以直接使用。
⑥父类的共有数据部分,如果子类需要直接调用可以定义为protected访问控制
⑦若子类都必须拥有一个共有行为,那么就可以定义一个纯虚函数=0,纯虚函数的存在,要求子类必须自己定义这个函数(若不自行定义,子类仍然是个抽象类),可以选择利用父类原有的缺省定义,也可以选择自己定义。
父类纯虚函数的声明只是提供一个共有的接口,而它的缺省定义 只是给 子类用的一个默认方法,对于它是纯虚函数以及父类不可实例化这个事实并没有做出任何改变,也就是不对父类产生影响。但是子类就可以 选择它的默认方法了,也可以选择自己重新定义
class B{
public:
virtual ~B() {cout<<"B";};
virtual void fun() =0;
};
void B::fun() {cout<<1;}//缺省定义
class A:public B{
public:
~A() {cout<<"A";};
void fun() { B::fun();}//子类必须重新定义,选择默认必须用基类class名加::使用。
};
编程例子:
①怪兽PK(基本子类)
一个游戏中有很多怪物(Monster),怪物之间可能要发生战斗(fight),
每场战斗都是一个怪物与另一怪物之间的一对一战斗。每个怪物都有自己
的速度(Speed)、生命值(hitpoint)、攻击力值(damage)和防御力值(defense);
战斗时,两个怪物依次攻击对方,即怪物a首先攻击怪物b, 然后轮到怪物b
攻击怪物a,之后,怪物a再次攻击怪物b,…,直到一方生命值为0;
战斗时,由速度快的一方首先发起攻击;若速度一样,比较生命值,由高者首先攻击;
若生命值也相等,比较攻击力,由高者首先攻击;若攻击力还相等,比较防御力,由
高者首先攻击;若四项都相等,则选择任一方首先攻击;
请根据你对上述描述的理解,定义并实现怪物类Monster,Cat,Dog成员的设计可以任意,
但要求该类至少有一个成员函数fight,用来描述与另外一个怪物进行战斗的过程。
不必考虑怪物的生命值减少至0后如何处理。
class Monster{
public:
Monster(int a,int b,int c,int d):Speed(a),hitpoint(b),damage(c),defense(d) {}
virtual ~Monster() {}
virtual bool Attack(Monster * other)=0; //纯虚函数,父类无法实例化
virtual bool fight(Monster * other);
virtual bool FirstAttack(Monster * other);
int Getdefense() const { return defense;}
int Gethitpoint() const {return hitpoint;}
int Getdamage() const {return damage;}
int GetSpeed() const {return Speed;}
void ReduceHP(int harm) { hitpoint-=harm;}
private:
int Speed;
int hitpoint;
int damage;
int defense;
};
class Cat:public Monster{
public:
Cat(int a,int b,int c,int d):Monster(a,b,c,d) {}
bool Attack(Monster * other){
int Harm=Getdamage()*2-other->Getdefense();
if(Harm<1) Harm=1;
other->ReduceHP(Harm);
if(other->Gethitpoint()<0) return true;
}
};
class Dog:public Monster{
public:
Dog(int a,int b,int c,int d):Monster(a,b,c,d) {}
bool Attack(Monster * other){}
};
②饮料加配料(子类代替名字,抽象出来)
#includeclass Condiment{ public: Condiment(const string Name,int Price):name(Name),price(Price){} virtual ~Condiment() {} int Getprice() const { return price;} const string GetName() const {return name;} private: const string name; int price; }; class Strawberry:public Condiment{ public: Strawberry():Condiment("草莓",2) {} }; class Pudding:public Condiment{ public: Pudding():Condiment("布丁",3) {} }; class Drink{ public: Drink(const string Name,int Price):name(Name),price(Price) {} virtual ~Drink() {if(num-1==1) delete p; else delete[] p;} void ShowPrice() { for(int i=0;i Getprice(); cout< GetName(); } cout<



