rpg.cpp:
#include <iostream>using namespace std;/*模拟一个游戏场景有一个英雄:初始所有属性为1atk,def,apd,hp游戏当中有以下3种武器长剑Sword: 装备该武器获得 +1atx,+1def短剑Blade: 装备该武器获得 +1atk,+1spd斧头Axe: 装备该武器获得 +1atk,+1hp要求英雄写一个函数:equipweapon 装备武器实现效果:装备不同武器英雄获得不同的属性加成
*/class Hero;class Weapon
{int atk;
public:Weapon():atk(1){}virtual ~Weapon(){}void set_atk(int atk){this->atk = atk;}int get_atk(){return atk;}virtual void equip(Hero &h);
};class Sword:public Weapon
{int def;
public:Sword():def(1){}void set_def(int def){this->def = def;}int get_def(){return def;}void equip(Hero &h) override;
};class Blade:public Weapon
{int spd;
public:Blade():spd(1){}void set_spd(int spd){this->spd = spd;}int get_spd(){return spd;}void equip(Hero &h) override;
};class Axe:public Weapon
{int hp;
public:Axe():hp(1){}void set_hp(int hp){this->hp = hp;}int get_hp(){return hp;}void equip(Hero &h) override;
};class Hero
{int atk;int def;int spd;int hp;Weapon * current_weapon;
public:Hero():atk(1),def(1),spd(1),hp(1),current_weapon(new Weapon){}~Hero(){delete current_weapon;}void set_atk(int atk){this->atk = atk;}int get_atk(){return atk;}void set_def(int def){this->def = def;}int get_def(){return def;}void set_spd(int spd){this->spd = spd;}int get_spd(){return spd;}void set_hp(int hp){this->hp = hp;}int get_hp(){return hp;}void equip_weapon(Weapon *w);void show();
};void Weapon::equip(Hero &h)
{int new_atk = h.get_atk() + this->get_atk();h.set_atk(new_atk);
}void Sword::equip(Hero &h)
{Weapon::equip(h);int new_def = h.get_def() + def;h.set_def(new_def);
}void Blade::equip(Hero &h)
{Weapon::equip(h);int new_spd = h.get_spd() + spd;h.set_spd(new_spd);}void Axe::equip(Hero &h)
{Weapon::equip(h);int new_hp = h.get_hp() + hp;h.set_hp(new_hp);
}void Hero::equip_weapon(Weapon *w)
{delete current_weapon;current_weapon = w;w->equip(*this);}void Hero::show()
{cout << "******** 英雄属性 ********" << endl<< " " << "atk = " << atk << endl<< " " << "def = " << def << endl<< " " << "spd = " << spd << endl<< " " << "hp = \t" << hp << endl<< "**************************" << endl;
}int main()
{Hero h1,h2,h3;h1.equip_weapon(new Sword);h2.equip_weapon(new Blade);h3.equip_weapon(new Axe);h1.show();h2.show();h3.show();return 0;
}
通过虚函数解决菱形继承产生的二义性问题
A --------公共基类/ \B C --------中间子类\ /D --------汇集子类
B类中会继承A类的成员,C类中也继承A类的成员,
D类中汇集成B和C中的所有成员 ------>导致A类中的内容,在D类中存在两份
有可能造成代码膨胀
#include <iostream>
using namespace std;
class A
{
public:int a;A():a(9){cout << "A构造" << endl;}
};
class B:public A
{
public:int b;B():b(0){cout << "B构造" << endl;}
};
class C:public A
{int c;
public://因为继承顺序是先继承B,再继承A,所以B先构造结束,后A构造结束,最后C构造结束//和初始化列表中的调用顺序无关C():c(6),A(){cout << "C构造" << endl;}void show();
};
class D:public B,public C
{void show_a(){//cout << a << endl; //因为中间基类中存在两种方式可以找到acout << B::a << endl; //存在于B类中的A类继承下来的acout << C::a << endl; //存在于C类中的A类继承下来的a}
};
int main()
{C c1;c1.show();return 0;
}
虚继承(virtual)
#include <iostream>using namespace std;class Person
{int age; //4字节string name; //32字节 +4对齐 36
public:Person(){}Person(int age,string name):age(age),name(name){}virtual void show(); //虚指针 8字节
}; //48class Stu:public Person // 继承Person 48
{double score; //56
public:Stu(){}Stu(int age,string name,double score):Person(age,name),score(score){}void show(); //对虚指针指向的虚函数表中的show进行重写
}; //56void Person::show()
{cout << "Person 中的show函数 " << endl;cout << "age = " << age << endl;cout << "name = " << name << endl;
}void Stu::show()
{cout << "Stu 中的show函数 " << endl;cout << "score = " << score << endl;
}int main()
{cout << sizeof (Person) << endl;cout << sizeof (Stu) << endl;Stu s1(18,"张三",99);Person &rp = s1;rp.show();rp.Person::show();return 0;
}
在菱形继承中,由于汇集子类中会保存两份公共基类的内容造成二义性问题,所以通常两个中间子类会虚继承公共基类 ------>在汇集子类中就只存在一份公共基类的内容
#include <iostream>
using namespace std;
class A
{
public:int a;A():a(9){cout << "A构造" << endl;}
};
//中间子类虚继承公共基类A
class B:virtual public A
{
public:int b;B():b(0),A(){cout << "B构造" << endl;}
};
class C:virtual public A
{int c;
public://因为继承顺序是先继承B,再继承A,所以B先构造结束,后A构造结束,最后C构造结束//和初始化列表中的调用顺序无关C():c(6),A(){cout << "C构造" << endl;}void show();
};
class D:public B,public C
{//汇集子类的构造函数中对于公共基类的构造,需要直接调用公共基类的构造函数即可D():B(),C(),A(){}void show_a(){//不加virtual,有两份A中的acout << a << endl; //由于我们使用了虚继承,所以D类中只有一份从公共基类中继承下来的acout << B::A::a << endl;cout << C::A::a << endl;}
};
int main()
{C c1;c1.show();return 0;
}