1. 程式人生 > >[實驗6]類的繼承與多態

[實驗6]類的繼承與多態

結合 github arc 成員 設計 技術 abc col 技術分享

一、實驗目的

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 芯片:計算兩位整數的加法

(m+n)、計算兩位整數的除法(m/n)

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]類的繼承與多態