实验6:类的继承和多态

南京信息工程大学实验报告

实验名称 类的继承和多态 实验日期 2018-5-29 得分 指导教师 耿学华 系 计软院 专业 计嵌+软嵌 年级 2017 级 班次 (1) 姓名 施昊阳 学号 20161334026

一、实验目的

  • 理解类的继承和派生机制
  • 掌握派生类的定义和使用
  • 掌握派生类成员的标识与访问中同名覆盖原则、二元作用域分辨符和虚基类的用法
  • 掌握派生类构造函数和析构函数的定义及调用次序
  • 理解运算符重载的目的,掌握运算符重载函数的编写方法

二、实验准备

  • 类的继承和派生
    请结合第 7 章课件和教材复习以下内容:

    • 引入继承和派生机制的目的
    • 基本概念:继承、派生、基类、直接基类、间接基类、派生类
    • 语法:
      • 派生类定义的语法格式(单重继承、多重继承);
      • 派生类构造函数极其初始化列表写法
    • 派生类成员的标识与访问
      • 同名覆盖指的是什么?
      • 二元作用域分辨符在什么情况下使用?
      • 什么是虚基类?引入虚基类的目的是什么?如何使用?
  • 运算符重载
    请结合第 8 章课件和教材学习以下内容:

    • 运算符重载的目的
    • 运算符重载的规则和限制
    • 运算符重载函数的语法格式
    • 运算符重载时,究竟重载为类的成员函数,还是友元,还是普通函数,需要综合考虑哪些因素?

三、实验内容

  • 某计算机硬件系统,为了实现特定的功能,在某个子模块设计了 ABC 三款芯片用于
    数字计算。各个芯片的计算功能如下:
    A 芯片:计算两位整数的加法(m+n)、计算两位整数的减法(m-n)
    B 芯片:计算两位整数的加法(m+n)、计算两位整数的乘法(m*n)
    C 芯片:计算两位整数的加法(m+n)、计算两位整数的除法(m/n)
    为 ABC 三个芯片分别定义类,描述上述芯片的功能,并在 main 函数中测试这三个类。
    (提示:利用类的继承和派生,抽象出共有属性和操作作为基类。)
  • 定义一个车(vehicle)基类,具有数据成员 maxspeed, weight(均为 int 型), 函数成员 run(), stop(),由此派生出自行车(bicycle)类、汽车(motorcar)类。其中, bicycle 类新增数据成员高度(height),motorcar 类新增数据成员座位数(seatnum)属性。再从 bicycle 和 motorcar 派生出摩托车(motorcycle)类,并在主程序中测试这个类。(每个类都要求定义构造函数和析构函数)
    (提示: ① 注意把 vehicle 设置为虚基类; ② run(), stop()函数体,通过输出字符串run, stop 简单模拟。)
  • 基于「实验 4 类和对象-2」中设计并实现的类 Fraction,创建派生类 iFraction,用以
    描述如下形式的分数:
    \(1\frac 2 3\)
    要求:

    • 更新 Fraction 类
      为 Fraction 类编写运算符+、-、、/重载函数,实现在 main 函数中直接用+、-、、/进行 Fraction 类运算。
    • 设计并实现派生 iFraction 类
      • 为派生类 iFraction 定义构造函数,实现 iFraction 对象的初始化
      • 为派生类 iFraction 增加一个成员函数,用于在屏幕上显示 iFraction 对象
    • 设计一个普通函数 convertF()用于对 iFraction 类对象进行规范化处理。(选做
      (提示:把 convertF()设计为 Fraction 类和 iFraction 类的友元函数)
      例如:(更多情形请自行考虑)
      \(\frac 5 3 \to 1 \frac 2 3\)
  • 以多文件结构方式编写(fraction.h, fraction.cpp, ifraction.h, ifraction.cpp, main.cpp)
    选做
    基于提供的程序文件,补足并扩充程序,实现一个多类型玩家角色扮演游戏。
    在本次实验附件包 ex4 中有如下文件:
    container.h, container.cpp, player.h, player.cpp, swordsman.h, swordsman.cpp, main.cpp

    • 阅读源码,理解并补足程序,让程序运行生效。
      其中,程序中出现有????????之处,是需要补足的部分。
    • 画出这个角色扮演游戏 UML 类图,尤其是类和类之间的关系
    • 设计并实现 archer 类和 mage 类。在 UML 类图中也加进这两个新类。
    • 修改 main 函数,随机生成不同角色的敌人,并保证程序正常运行。
    • 为游戏增加其它元素,完善游戏的可玩性、趣味性,等。
      (说明:这道涉及虚函数、运行时多态。你可以在第 8 章学完后尝试编写,或者,在尝试编写这道题的过程中,学习第 8 章虚函数和运行时多态的知识。)

四、实验结论

  • 实验内容 1

    • LM51.h

      #include<bits/stdc++.h>
      using namespace std;
      #ifndef _LM51_H
      #define _LM51_H
      class LM51{
      protected:
              int m,n;
      public:
      int plus();
      LM51(int M=2016,int N=133);
      ~LM51();
      };
      #endif
    • LM51.cpp
      #include"LM51.h"
      int LM51::plus() {
      cout << "LM51.plus " << endl;
      return m+n;
      }
      LM51::LM51(int M,int N) {
      cout << "Constru
      }ctor LM51 is called" << endl;
      m=M;
      n=N;
      LM51::~LM51() {
      cout << "Deconstructor LM51 is called" << endl;
      }
    • A.h
      #include"LM51.h"
      #ifndef _A_h
      #define _A_h
      class A:public LM51{
      public :
      A(int M=2016,int N=133);
      int minus();
      ~A();
      };
      #endif
    • A.cpp
      #include"A.h"
      A::A(int M,int N){
      m=M;
      n=N;
      cout << "Constructor A is called" << endl;
      }
      int A::minus() {
      cout << "A.minus " << endl;
      return m-n;
      }
      A::~A() {
      cout << "Deconstructor A is called" << endl;
      }
    • B.h
      #include"LM51.h"
      #ifndef _B_h
      #define _B
      class B:public LM51{
      public :
      B(int M=2016,int N=133);
      int mulip();
      ~B();
      };
      #endif
    • B.cpp
      #include"B.h"
      B::B(int M,int N){
      m=M;
      n=N;
      cout << "Constructor B is called" << endl;
      }
      int B::mulip() {
      cout << "B.mulip " << endl;
      return m*n;
      }
      B::~B() {
      cout << "Deconstructor B is called" << endl;
      }
    • C.h
      #include"LM51.h"
      #ifndef _C_h
      #define _C
      class C:public LM51{
      public :
      C(int M=2016,int N=133);
      double divi();
      ~C();
      };
      #endif
    • C.cpp
      #include"C.h"
      C::C(int M,int N){
      m=M;
      n=N;
      cout << "Constructor C is called" << endl;
      }
      double C::divi() {
      cout << "C.divi " << endl;
      return m/n;
      }
      C::~C() {
      cout << "Deconstructor C is called" << endl;
      }
    • Main.cpp
      #include<bits/stdc++.h>
      #include "A.h"
      #include "B.h"
      #include "C.h"
      using namespace std;
      int main(){
      A a(20,16);
      cout<<a.plus()<<endl;
      cout<<a.minus()<<endl;
      B b(13,1);
      cout<<b.plus()<<endl;
      cout<<b.mulip()<<endl;
      C c(40,26);
      cout<<c.plus()<<endl;
      cout<<c.divi()<<endl;
      return 0;
      }
    • Screenshot:
  • 实验内容 2
    • vehicle.h

      #ifndef _VEHICLE
      #define _VEHICLE
      class vehicle{
      protected:
      int maxspeed,weight;
      public:
      void run();
      void stop();
      vehicle(int M=100,int W=1000);
      ~vehicle();
      };
      #endif
    • vehicle.cpp
      #include "vehicle.h"
      void vehicle::run() {
      cout<<"run"<<endl;
      }
      void vehicle::stop() {
      cout<<"stop"<<endl;
      }
      vehicle::vehicle(int M,int W) {
      maxspeed=M;
      weight=W;
      cout<<"Constructor vehicle is called"<<endl;
      }
      vehicle::~vehicle() {
      cout<<"Deconstructor vehicle is called"<<endl;
      }
    • bicycle.h
      #ifndef _BICYCLE
      #define _BICYCLE
      class bicycle:virtual public vehicle{
      protected:
      int height;
      public:
      bicycle(int M=100,int W=1000,int H=2):vehicle(M,W);
      ~bicycle();
      };
      #endif
    • bicycle.cpp
      #include"bicycle.h"
      bicycle::bicycle(int M,int W,int H):vehicle(M,W) {
      height=H;
      cout<<"Constructor bicycle is called"<<endl;
      }
      bicycle::~bicycle() {
      cout<<"Deconstructor bicycle is called"<<endl;
      }
    • motorcar.h
      #ifndef _MOTORCAR
      #define _MOTORCAR
      class motorcar:virtual public vehicle{
      protected:
      int seatnum;
      public:
      motorcar(int M,int W,int H):vehicle(M,W);
      ~motorcar();
      };
      #endif
    • motorcar.cpp
      #include"motocar.h"
      motocar::motorcar(int M,int W,int S):vehicle(M,W) {
      seatnum=S;
      cout<<"Constructor motorcar is called"<<endl;
      }
      motocar::~motorcar() {
      cout<<"Deconstructor motorcar is called"<<endl;
      }
    • motorcycle.h
      #ifndef _MOTORCYCLE
      #define _MOTORCYCLE
      class motorcycle:public bicycle,public motorca{
      public:
      motorcycle(int M=100,int W=1000,int S=4,int H=2):vehicle(M,W);
      ~motorcycle();
      };
      #endif
    • motorcycle.cpp
      #include"motorcycle.h"
      motorcycle::motorcycle(int M,int W,int S,int H):vehicle(M,W) {
      seatnum=S;
      height=H;
      cout<<"Constructor motorcycle is called"<<endl;
      }
      motorcycle::~motorcycle() {
      cout<<"Deconstructor motorcycle is called"<<endl;
      }
    • Main.cpp
      #include"vehicle.h"
      #include"bicycle.h"
      #include"motorcar.h"
      #include"motorcycle.h"
      int main(){
      vehicle a;
      a.run();
      a.stop();
      bicycle b;
      b.run();
      b.stop();
      motorcar c;
      c.run();
      c.stop();
      motorcycle d;
      d.run();
      d.stop();
      return 0;
      }

    -Screenshot:

  • 实验内容 3
    • iFraction.h

      #include "Fraction.h"
      #ifndef _IFRACTION
      #define _IFRACTION
      class iFraction:public Fraction{
      private:
      int i;
      public:
      iFraction(int t=0,int b=1,int I=0):Fraction(t,b){i=I;}
      iFraction(const iFraction &c0):Fraction(c0){i=c0.i;}
      void print();
      friend iFraction convertF(const iFraction &c0);
      };
      #endif
    • iFraction.cpp
      #include"iFraction.h"
      void iFraction::print() {
      if(top==0){cout<<i<<endl;
      return ;
      }
      cout<<setw(4)<<setfill(' ')<<top<<endl;
      cout<<setw(3)<<setfill(' ')<<i<<'-'<<endl;
      cout<<setw(4)<<setfill(' ')<<bottom<<endl;
      }
      iFraction convertF(const iFraction &c0) {
      iFraction tmp(c0);
      tmp.simplify();
      int tt=tmp.top/tmp.bottom;
      tmp.i+=tt;
      tmp.top%=tmp.bottom;
      return tmp;
      }
    • Fraction.h
      #include<iostream>
      #include<cmath>
      #include <iomanip>
      #ifndef _FRACTION
      #define _FRACTION
      using namespace std;
      class Fraction {
      protected:
      int top, bottom;
      int gcd(int a, int b);
      public:
      Fraction(int t, int b);
      Fraction(int t);
      Fraction();
      void simplify();
      void add(Fraction c0);
      void subtract(Fraction c0);
      void multiple(Fraction c0);
      void divde(Fraction c0);
      bool compare(Fraction c0);
      void readln();
      void writeln();
      double todecimal();
      friend Fraction operator +(const Fraction &c0,const Fraction &c1);
      friend Fraction operator -(const Fraction &c0,const Fraction &c1);
      friend Fraction operator *(const Fraction &c0,const Fraction &c1);
      friend Fraction operator /(const Fraction &c0,const Fraction &c1);
      Fraction &operator +=(const Fraction &c0) {
          bottom = bottom * c0.bottom;
          top = top * c0.bottom + c0.top * bottom;
          simplify();
          return *this;
      }
      Fraction &operator -=(const Fraction &c0) {
          bottom = bottom * c0.bottom;
          top = top * c0.bottom - c0.top * bottom;
          if(bottom < 0) {
              top = - top;
              bottom = - bottom;
          }
          simplify();
          return *this;
      }
      Fraction &operator *=(const Fraction &c0) {
          top *= c0.top;
          bottom *= c0.bottom;
          simplify();
          return *this;
      }
      Fraction &operator /=(const Fraction &c0) {
          if(c0.top == 0) {
              return *this;
          }
          top *= c0.bottom;
          bottom *= c0.top;
          simplify();
          return *this;
      }
      };
      #endif
    • Fraction.cpp
      #include"Fraction.h"
      int Fraction::  gcd(int a, int b) {
      return a % b == 0 ? b : gcd(b, a%b);
      }
      Fraction:: Fraction(int t, int b) {
      top = t;
      bottom = b;
      }
      Fraction:: Fraction(int t) {
      top = t;
      bottom = 1;
      }
      Fraction:: Fraction() {
      top = 0;
      bottom = 1;
      }
      void Fraction:: simplify() {
      if(bottom < 0) {
      top = - top;
      bottom = - bottom;
      }
      int g = gcd(abs(top),abs(bottom));
      top /= g;
      bottom /= g;
      }
      void Fraction:: add(Fraction c0) {
      bottom = bottom * c0.bottom;
      top = top * c0.bottom + c0.top * bottom;
      simplify();
      }
      void Fraction:: subtract(Fraction c0) {
      bottom = bottom * c0.bottom;
      top = top * c0.bottom - c0.top * bottom;
      if(bottom < 0) {
      top = - top;
      bottom = - bottom;
      }
      simplify();
      }
      void Fraction:: multiple(Fraction c0) {
      top *= c0.top;
      bottom *= c0.bottom;
      simplify();
      }
      void Fraction:: divde(Fraction c0) {
      if(c0.top == 0) {
      cout << "Error: Zero can't be divided.\n";
      return ;
      }
      top *= c0.bottom;
      bottom *= c0.top;
      simplify();
      }
      bool Fraction:: compare(Fraction c0) {
      return top * gcd(bottom, c0.bottom) - c0.top
         * gcd(bottom, c0.bottom) > 0 ? true : false;
      }
      void Fraction:: readln() {
      cout << "Plz input the Numerator and Denominator" << endl;
      cin >> top;
      int tmp;
      cin >> tmp;
      while (tmp == 0) {
      cout << "Zero can't be the Denominator, plz try again!" << endl;
      cin >> tmp;
      }
      bottom = tmp;
      }
      void Fraction:: writeln() {
      if(bottom != 1) cout << top << "/" << bottom << endl;
      else cout << top <<endl;
      }
      double Fraction:: todecimal() {
      return (double)top / bottom;
      }
      Fraction operator +(const Fraction &c0,const Fraction &c1) {
      Fraction tmp;
      tmp.bottom = c0.bottom * c1.bottom;
      tmp.top = c1.top * c0.bottom + c0.top * c1.bottom;
      tmp.simplify();
      return tmp;
      }
      Fraction operator -(const Fraction &c0,const Fraction &c1) {
      Fraction tmp;
      tmp.bottom = c0.bottom * c1.bottom;
      tmp.top = c0.top * c1.bottom - c1.top * c0.bottom;
      if(tmp.bottom < 0) {
      tmp.top = - tmp.top;
      tmp.bottom = - tmp.bottom;
      }
      tmp.simplify();
      return tmp;
      }
      Fraction operator *(const Fraction &c0,const Fraction &c1) {
      Fraction tmp;
      tmp.top = c0.top * c1.top;
      tmp.bottom = c0.bottom * c1.bottom;
      tmp.simplify();
      return tmp;
      }
      Fraction operator /(const Fraction &c0,const Fraction &c1) {
      Fraction tmp;
      if(c0.top == 0 || c1.top == 0) {
      return tmp;
      }
      tmp.top = c0.top * c1.bottom;
      tmp.bottom = c0.bottom * c1.top;
      tmp.simplify();
      return tmp;
      }
    • Main.cpp
      #include "Fraction.h"
      #include "iFraction.h"
      int main() {
      Fraction c1 (11,-22);
      Fraction c2 (4);
      Fraction c3 ;
      c1 = c1 + c2;
      cout << "c1 + c2 = ";c1.writeln();
      c1 += c2;
      cout << "c1 += c2 , c1 = ";c1.writeln();
      c1 = c1 - c2;
      cout << "c1 - c2 = ";c1.writeln();
      c1 -= c2;
      cout << "c1 -= c2 , c1 = ";c1.writeln();
      c1 = c1 * c2;
      cout << "c1 * c2 = ";c1.writeln();
      c1 *= c2;
      cout << "c1 *= c2 , c1 = ";c1.writeln();
      c1 = c1 / c2;
      cout << "c1 / c2 = ";c1.writeln();
      c1 /= c2;
      cout << "c1 /= c2 , c1 = ";c1.writeln();
      cout << "c4="<<endl;
      iFraction c4(4,2,-3);
      c4.print();
      c4=convertF(c4);
      cout<<"c4 = convertF(c4) = "<<endl;
      c4.print();
      return 0;
      }
    • Screenshot:
  • 实验内容4:
    Github Address : https://github.com/shylocks/ex_6_4.git
    *Press Commits Buttom to see changes.
    UML :

五、实验总结与体会

C++ 与 Java 之间关于“类的继承与多态”一些概念的重叠:
C++ Java
虚函数 普通函数
纯虚函数 抽象函数
抽象类 抽象类
虚基类 接口
(C++先辈万物之父说)

原文地址:https://www.cnblogs.com/shy-/p/9106943.html

时间: 2024-10-09 09:45:13

实验6:类的继承和多态的相关文章

实验五--类的继承派生多态二次练习

实验目的 1. 理解运行时多态 2. 掌握虚函数和抽象类 实验准备 1. 概念 多态,运行时多态 虚函数, 纯虚函数, 抽象类 2. 语法和应用 虚函数的定义和使用纯虚函数.抽象类的定义和使用 实验内容 设计并实现一个机器宠物类MachinePets. 每个机器宠物有如下信息:昵称(nickname) 每个机器宠物有如下成员函数: 带参数的构造函数MachinePets(const string s) ,为机器宠物初始化昵称. 纯虚函数string talk()为机器宠物派生类提供宠物叫声的统一

实验6 类的继承和多态

四.实验结论 1.实验内容1 Base.h #ifndef Base_h #define Base_h using namespace std; class Base { public: Base (int m0 ,int n0):m(m0),n(n0){} int add (){return m+n;}; int getm() const {return m;}; int getn() const {return n;}; private: int m, n; }; #endif /*Base

python之7-2类的继承与多态

类的继承的意思就如同父子关系一样,这个儿子继承了父亲的一切,但是在某些地方(属性)相同的时候,儿子的属性大于老子的属性(覆盖),最底层类,总会继承最接近它的那个类的属性init 类的多态总是和继承相连的,没有继承,就没有多态一说.一个子类的实例,它即属于这个子类,也属于父类,比如:父亲A和儿子B,儿子B即属于儿子类,也属于人类,但是它不属于父亲类 多态是面向对象语言的一个基本特性,多态意味着变量并不知道引用的对象是什么,根据引用对象的不同表现不同的行为方式.在处理多态对象时,只需要关注它的接口即

【游戏开发】在Lua中实现面向对象特性——模拟类、继承、多态

一.简介 Lua是一门非常强大.非常灵活的脚本语言,自它从发明以来,无数的游戏使用了Lua作为开发语言.但是作为一款脚本语言,Lua也有着自己的不足,那就是它本身并没有提供面向对象的特性,而游戏开发是一项庞大复杂的工程,如果没有面向对象功能势必会为开发带来一定的不便.不过幸好Lua中有table这样强大的数据结构,利用它再结合元表(metatable),我们便可以很方便地在Lua中模拟出类.继承和多态等面向对象编程具有的特性. 二.前提知识 按照惯例,我们还是先来熟悉一下必要的前提知识,以便方便

综合运用类、继承、多态,完成一个公司人员管理类层次结构(未完待续)

1.Target /*综合运用类.继承.多态等技术,完成一个公司人员管理类层次结构,用来描述人员信息等, 重载各种运算符,完成数据库内容的赋值.添加.工资增长等.*/ 2.Code #include <iostream> #include <cstring> #include <string> #include <cstdio> #include<cstdlib> #define TECH const string name, const int

类的继承和多态细思

类的继承和多态细思 一.前言   类的继承和多态光靠概念和想象是不够的,我们需要编码去分析之,因此我使用代码来说明一些很难分清的东西. 二.分析代码 A类代码: package zyr.study.poly; public class A { public A(){ System.out.println("初始化A..."); } public String show(A obj) { return ("A and A"); } public String show

python类的继承和多态

python类的继承和多态 现在属于是老年人的脑子,东西写着写着就忘了,东西记着记着就不知道了.之前学C++的时候就把类.对象这块弄得乱七八糟,现在是因为很想玩python,所以就看看python的类和对象. 就像说的,类有三个特征:封装.继承.多态. 1.封装:类封装了一些方法,可通过一定的规则约定方法进行访问权限. C++中的成员变量有public.private.ptotected. 在python中,默认的成员变量都是public的,如果成员变量前面是加两个下划线,表示该成员变量是私有的

实验4 类的继承、派生和多态(1)

实验目的 1. 理解类的继承和派生机制 2. 掌握派生类的定义和使用 3. 理解和掌握派生类成员的标识和访问中同名覆盖原则.二元作用域分辨符和虚基类的用法 4. 掌握派生类构造函数和析构函数的定义及调用次序 5. 理解运算符重载的目的,掌握运算符重载函数的编写方法 实验准备 1. 类的继承和派生 引入继承和派生机制的目的 基本概念:继承.派生.基类.直接基类.间接基类 .派生类 语法 派生类定义的语法格式(单重继承和多重继承) 派生类构造函数及其初始化列表书写形式 派生类成员的标识与访问 同名覆

c++实验四 类的继承、派生和多态

实验目的 1. 理解类的继承和派生机制 2. 掌握派生类的定义和使用 3. 理解和掌握派生类成员的标识和访问中同名覆盖原则.二元作用域分辨符和虚基类的用法 4. 掌握派生类构造函数和析构函数的定义及调用次序 5. 理解运算符重载的目的,掌握运算符重载函数的编写方法 实验内容 一.ElectricCar类 #ifndef BATTERY_H #define BATTERY_H class Battery { public: Battery(int nb = 70); int showbattery