第五次实验
第一题(1)
1 // 示例:多层继承,没有使用虚函数 2 #include <iostream> 3 using namespace std; 4 5 // 基类Base1 6 class Base1 { 7 public: 8 void display() const {cout << "Base1::display()" << endl; } 9 }; 10 11 // 派生类Base2,公有继承自Base1 12 class Base2:public Base1{ 13 public: 14 void display() const { cout << "Base2::display()" << endl; } 15 }; 16 17 // 派生类Derived,公有继承自Base2 18 class Derived: public Base2 { 19 public: 20 void display() const { cout << "Derived::display()" << endl;} 21 }; 22 23 void fun(Base1 *ptr) { 24 ptr->display(); 25 } 26 27 28 int main() { 29 30 Base1 base1; 31 Base2 base2; 32 Derived derived; 33 34 // 观察:通过"对象名.成员名"访问类族中同名成员函数时运行结果 35 base1.display(); 36 base2.display(); 37 derived.display(); 38 39 // 观察:通过公共接口函数fun(),利用基类指针访问同名成员函数时运行结果 40 fun(&base1); 41 fun(&base2); 42 fun(&derived); 43 44 return 0; 45 }
没有使用虚函数,当通过基类指针指向派生类对象的成员函数时,调用的只是继承来的基类的成员函数!
(2)
1 // 示例:多层继承,使用虚函数 2 #include <iostream> 3 using namespace std; 4 5 // 基类Base1 6 class Base1 { 7 public: 8 virtual void display() const {cout << "Base1::display()" << endl; } // 相较于ex1_1.cpp, 基类Base1中成员函数前添加了关键字virtual 9 }; 10 11 // 派生类Base2,公有继承自Base1 12 class Base2:public Base1{ 13 public: 14 void display() const { cout << "Base2::display()" << endl; } 15 }; 16 17 // 派生类Derived,公有继承自Base2 18 class Derived: public Base2 { 19 public: 20 void display() const { cout << "Derived::display()" << endl;} 21 }; 22 23 void fun(Base1 *ptr) { 24 ptr->display(); 25 } 26 27 28 int main() { 29 30 Base1 base1; 31 Base2 base2; 32 Derived derived; 33 34 // 观察:通过"对象名.成员名"访问类族中同名成员函数时运行结果 35 base1.display(); 36 base2.display(); 37 derived.display(); 38 39 // 观察:通过公共接口函数fun(),利用基类指针访问同名成员函数时运行结果 40 fun(&base1); 41 fun(&base2); 42 fun(&derived); 43 44 return 0; 45 }
使用虚函数时通过调用基类的指针指向派生类的对象的话,会调用派生类中的函数,基类的函数被覆盖了
第二题
1 #include <iostream> 2 #include <cmath> 3 using namespace std; 4 const float PI = 3.14; 5 6 //抽象类Shape 7 class Shape { 8 public: 9 virtual float area()=0; // 纯虚函数 10 }; 11 12 // 派生类Rectangle供有继承自类Shape 13 class Rectangle: public Shape { 14 public: 15 Rectangle() {} 16 Rectangle(float l, float w): length(l), width(w) { } 17 float area() { return length*width; } 18 private: 19 float length, width; 20 }; 21 22 // 派生类Cirle公有继承自类Shape 23 class Circle: public Shape { 24 public: 25 Circle() {} 26 Circle(float r): radius(r) { } 27 float area() { return PI*radius*radius; } 28 private: 29 float radius; 30 }; 31 32 33 // 派生类Triangle公有继承自类Shape 34 class Triangle: public Shape { 35 public: 36 Triangle() {} 37 Triangle(float a, float b, float c):side1(a), side2(b), side3(c) { } 38 float area() { 39 float t; 40 t = (side1 + side2 + side3) / 2; 41 return sqrt( t*(t-side1)*(t-side2)*(t-side3) ); 42 } 43 private: 44 float side1, side2, side3; 45 }; 46 47 // 接口函数,为打印图形面积提供了一个统一的功能接口,用于打印图形面积 48 // 形参是指向基类的指针,按照继承和派生机制中的赋值兼容原则,它也可以指向派生类的对象 49 void printArea(Shape *p) { 50 cout << p->area() << endl; 51 } 52 53 int main() { 54 Rectangle rect(3,4); 55 Circle cc(2); 56 Triangle tt(3,4,5); 57 58 printArea(&rect); 59 printArea(&cc); 60 printArea(&tt); 61 62 return 0; 63 }
纯虚函数的抽象类,自身无法构造对象,但是可以通过派生类构造对象实例,是多态的完美体现
第三题
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 class MachinePets 5 { 6 public: 7 MachinePets(const string s):nickname(s){} 8 virtual string talk()=0; 9 string getNickname(); 10 private: 11 string nickname; 12 }; 13 14 string MachinePets::getNickname() 15 { 16 return nickname; 17 } 18 19 20 21 class PetCats:public MachinePets 22 { 23 public: 24 PetCats(const string s):MachinePets(s){} 25 string talk(); 26 }; 27 28 string PetCats::talk() 29 { 30 return "says miao wu~"; 31 } 32 33 34 class PetDogs:public MachinePets 35 { 36 public: 37 PetDogs(const string s):MachinePets(s){} 38 string talk(); 39 }; 40 41 string PetDogs::talk() 42 { 43 return "says wang wang~"; 44 } 45 46 void play(MachinePets* p) 47 { 48 cout<<p->getNickname()<<p->talk()<<endl; 49 } 50 int main () 51 { 52 PetCats cat("miku"); 53 PetDogs dog("da huang"); 54 play(&cat); 55 play(&dog); 56 return 0; 57 }
第四题
1 #ifndef _CONTAINER //1???????? // Conditional compilation 2 #define _CONTAINER
1 bool container::useHeal() 2 { 3 numOfHeal--;//2_???????? 4 return 1; // use heal successfully 5 }
1 void player::transfer(player &p) 2 { 3 cout<<name<<" got"<<p.bag.nOfHeal()<<" Heal, and "<<p.bag.nOfMW()<<" Magic Water."<<endl; 4 system("pause"); 5 bag.set(p.bag.nOfHeal()+bag.nOfHeal(),p.bag.nOfMW()+bag.nOfMW());//3_??????????? 6 // set the character's bag, get opponent's items 7 }
1 // display character's job 2 void showinfo(player& p1,player& p2)//4_??????????????
1 class swordsman : public player//5_????????? // subclass swordsman publicly inherited from base player
1 if (human->death()) 2 { 3 system("cls"); 4 cout<<endl<<setw(50)<<"GAME OVER"<<endl; 5 human->isDead();//6_??????????? // player is dead, program is getting to its end, what should we do here? 6 system("pause"); 7 return 0; 8 }
1 //7_????????? // You win, program is getting to its end, what should we do here?
第七个空不知道该填什么,感觉不填也没关系
总结:多态是c++的重要特征,虚函数,纯虚函数,抽象类的使用要多加练习