[實驗6]類的繼承與多態
一、實驗目的
1.理解類的繼承和派生機制
2.掌握派生類的定義和使用
3.掌握派生類成員的標識與訪問中同名覆蓋原則、二元作用域分辨符和虛基類的用法
4.掌握派生類構造函數和析構函數的定義及調用次序
5.理解運算符重載的目的,掌握運算符重載函數的編寫方法
二、實驗準備
1. 類的繼承和派生
請結合第 7 章課件和教材復習以下內容:
(1)引入繼承和派生機制的目的
(2)基本概念:繼承、派生、基類、直接基類、間接基類、派生類
(3)語法:
① 派生類定義的語法格式(單重繼承、多重繼承);
② 派生類構造函數極其初始化列表寫法
(4)派生類成員的標識與訪問
① 同名覆蓋指的是什麽?
② 二元作用域分辨符在什麽情況下使用?
③ 什麽是虛基類?引入虛基類的目的是什麽?如何使用?
2. 運算符重載
請結合第 8 章課件和教材學習以下內容:
(1)運算符重載的目的
(2)運算符重載的規則和限制
(3)運算符重載函數的語法格式
(4)運算符重載時,究竟重載為類的成員函數,還是友元,還是普通函數,需要綜合考慮哪些因素?
三、實驗內容
1.某計算機硬件系統,為了實現特定的功能,在某個子模塊設計了 ABC 三款芯片用於數字計算。各個芯片的計算功能如下:
A 芯片:計算兩位整數的加法(m+n)、計算兩位整數的減法(m-n)
B 芯片:計算兩位整數的加法(m+n)、計算兩位整數的乘法(m*n)
C 芯片:計算兩位整數的加法
為 ABC 三個芯片分別定義類,描述上述芯片的功能,並在 main 函數中測試這三個類。
(提示:利用類的繼承和派生,抽象出共有屬性和操作作為基類。)
2.定義一個車(vehicle)基類,具有數據成員 maxspeed, weight(均為 int 型), 函數成員 run(), stop(),由此派生出自行車(bicycle)類、汽車(motorcar)類。其中, bicycle 類新增數據成員高度(height),motorcar 類新增數據成員座位數(seatnum)屬性。再從 bicycle和 motorcar 派生出摩托車(motorcycle)類,並在主程序中測試這個類。(每個類都要求定義構造函數和析構函數)(提示: ① 註意把 vehicle 設置為虛基類; ② run(), stop()函數體,通過輸出字符串 run, stop 簡單模擬。)
3.基於「實驗 4 類和對象-2」中設計並實現的類 Fraction,創建派生類 iFraction,用以描述如下形式的分數:
2
1 3
要求:
(1) 更新 Fraction 類
為 Fraction 類編寫運算符+、-、*、/重載函數,實現在 main 函數中直接用+、-、
*、/進行 Fraction 類運算。
(2)設計並實現派生 iFraction 類
① 為派生類 iFraction 定義構造函數,實現 iFraction 對象的初始化
② 為派生類 iFraction 增加一個成員函數,用於在屏幕上顯示 iFraction 對象
(3)設計一個普通函數 convertF()用於對 iFraction 類對象進行規範化處理。(*選做*)
(提示:把 convertF()設計為 Fraction 類和 iFraction 類的友元函數)例如:(更多情形請自行考慮)
5 2
3 → 1 3
(4)以多文件結構方式編寫(fraction.h, fraction.cpp, ifraction.h, ifraction.cpp, main.cpp)
4. (***選做***)
基於提供的程序文件,補足並擴充程序,實現一個多類型玩家角色扮演遊戲。在本次實驗附件包 ex4 中有如下文件:
container.h, container.cpp, player.h, player.cpp, swordsman.h, swordsman.cpp, main.cpp
(1)閱讀源碼,理解並補足程序,讓程序運行生效。
其中,程序中出現有????????之處,是需要補足的部分。
(2)畫出這個角色扮演遊戲 UML 類圖,尤其是類和類之間的關系
(3)設計並實現 archer 類和 mage 類。在UML 類圖中也加進這兩個新類。
(4)修改 main 函數,隨機生成不同角色的敵人,並保證程序正常運行。
(5)為遊戲增加其它元素,完善遊戲的可玩性、趣味性,等。
(說明:這道涉及虛函數、運行時多態。你可以在第 8 章學完後嘗試編寫,或者,
在嘗試編寫這道題的過程中,學習第 8 章虛函數和運行時多態的知識。)
四、實驗結論
1.實驗內容 1
采用多文件結構,給出每個文件完整源代碼,及運行測試截圖。
base.h:
#include<iostream> using namespace std; class base{ public: base(int a,int b):m(a),n(b){} int add(){ cout<<"m+n="<<m+n<<endl; } private: int m,n; };
A.h:
#include<iostream> using namespace std; class A:public base{ public: A(int a,int b):base(a,b){ m=a; n=b; } int minus(){ cout<<"m-n="<<m-n<<endl; } private: int m,n; };
B.h:
#include<iostream> using namespace std; class B:public base{ public: B(int a,int b):base(a,b){ m=a; n=b; } int mul(){ cout<<"m*n="<<m*n<<endl; } private: int m,n; };
C.h:
#include<iostream> using namespace std; class C:public base{ public: C(int a,int b):base(a,b){ m=a; n=b; } int div(){ cout<<"m/n="<<m/n<<endl; } private: int m,n; };
main.cpp:
#include<iostream> #include"base.h" #include"A.h" #include"B.h" #include"C.h" using namespace std; int main() { A a(15,8); a.add(); a.minus(); B b(6,5); b.add(); b.mul(); C c(20,4); c.add(); c.div(); return 0; }
2.實驗內容 2
vehicle.h
#include<iostream> using namespace std; class vehicle{ public: vehicle(int m,int w):maxspeed(m),weight(w){ cout<<"maxspeed:"<<maxspeed<<endl; cout<<"weight:"<<weight<<endl; } ~vehicle(){} void run(){ cout<<"run"<<endl; }; void stop(){ cout<<"stop"<<endl<<endl; }; private: int maxspeed,weight; };
bicycle.h
#include<iostream> using namespace std; class bicycle:virtual public vehicle{ public: bicycle(int m,int w,int h):vehicle(m,w){ height=h; cout<<"bicycle is coming"<<endl; cout<<"height:"<<height<<endl; } ~bicycle(){} private: int height; };
motorcar.h
#include<iostream> using namespace std; class motorcar:virtual public vehicle{ public: motorcar(int m,int w,int s):vehicle(m,w){ seatnum=s; cout<<"seatnum:"<<seatnum<<endl; } ~motorcar(){} private: int seatnum; };
motorcycle.h
#include<iostream> using namespace std; class motorcycle: public bicycle,public motorcar{ public: motorcycle(int m,int w,int h,int s):vehicle(m,w),bicycle(m,w,h),motorcar(m,w,s){} ~motorcycle(){} };
main.cpp
#include<iostream> #include"vehicle.h" #include"bicycle.h" #include"motorcar.h" #include"motorcycle.h" using namespace std; int main(){ vehicle a(200,100); a.run(); a.stop(); bicycle b(50,20,1); b.run(); b.stop(); motorcar c(150,60,2); c.run(); c.stop(); motorcycle d(100,40,1,2); d.run(); d.stop(); return 0; }
3.實驗內容 3
采用多文件結構,給出每個文件完整源代碼,及運行測試截圖。
Fraction.h
#include<iostream> class Fraction { public: Fraction(int t,int b); Fraction(int t); Fraction(); void show(); int zc(int t,int b); void simplify(); Fraction operator+(Fraction &b); Fraction operator-(Fraction &b); Fraction operator*(Fraction &b); Fraction operator/(Fraction &b); protected: int top; int bottom; };
Fraction.cpp
#include"Fraction.h" #include<iostream> #include<cmath> using namespace std; Fraction::Fraction(int t,int b) { top=t; bottom=b; } Fraction::Fraction(int t) { top=t; bottom=1; } Fraction::Fraction() { top=0; bottom=1; } int Fraction::zc(int t,int b) { if(t%b==0) return b; else zc(b,t%b); } void Fraction::simplify() { if(bottom<0) { top=-top; bottom=-bottom; } int z=zc(abs(top),abs(bottom)); top=top/z; bottom=bottom/z; } void Fraction::show(){ cout<<top<<"/"<<bottom<<endl; } Fraction Fraction::operator+(Fraction &b) { return Fraction(top*b.bottom+b.top*bottom,bottom*b.bottom); } Fraction Fraction::operator-(Fraction &b) { return Fraction(top*b.bottom-b.top*bottom,bottom*b.bottom); } Fraction Fraction::operator*(Fraction &b) { return Fraction(top*b.top,bottom*b.bottom); } Fraction Fraction::operator/(Fraction &b) { return Fraction(top*b.bottom,bottom*b.top); }
iFraction.h
#include"Fraction.h" class iFraction:public Fraction { private: int i; public: iFraction(int t=0,int b=1,int z=0):Fraction(t,b),i(z){} void print(); friend iFraction convertF(iFraction &p); };
Fraction.cpp
#include"iFraction.h" #include<iostream> using namespace std; void iFraction::print() { if(top==0) cout<<i<<endl; else if(i==0) { cout<<top<<endl; cout<<"-"<<endl; cout<<bottom<<endl; } else { cout<<" "<<top<<endl; cout<<i<<"-"<<endl; cout<<" "<<bottom<<endl; } } iFraction convertF(iFraction &p) { p.simplify(); p.i+=p.top/p.bottom; p.top%=p.bottom; return p; }
main.cpp
#include <iostream> #include "iFraction.h" using namespace std; int main() { Fraction a(-2,6); cout<<"a="; a.show(); Fraction b(3); cout<<"b="; b.show(); Fraction c; cout<<"c="; c.show(); c=a+b; cout<<"a+b="; c.show(); c=a-b; cout<<"a-b="; c.show(); c=a*b; cout<<"a*b="; c.show(); c=a/b; cout<<"a/b="; c.show(); iFraction d(15,6,2); cout<<"d="<<endl; d.print(); d=convertF(d); cout<<"convertF d="<<endl; d.print(); return 0; }
4. 實驗內容 4 (***選做***)
(1)簡潔陳述自己實現的遊戲功能;
(2)給出UML 類圖
(3)采用多文件結構,給出每個文件完整源代碼。
(這個程序源代碼文件比較多,如有 github 賬號,也可以直接附上遊戲項目文檔文件github 頁面地址)
[實驗6]類的繼承與多態