造福学弟学妹系列:C++继承和派生实验报告

将我们学校C++课的实验报告copy上来,希望能给未来的学弟学妹做参考

教材:C++语言程序设计(第四版) 清华大学出版社

 

 

一、实验目的

1、学习声明和使用类的继承关系,声明派生类

2、熟悉不同继承方式下对基类成员的访问控制

3、学习利用虚基类解决二义性问题

二、实验任务

1、声明一个基类Animal,有私有整型成员变量age,构造其派生类dog,在其成员函数SetAge(int n)中直接给age赋值,看看有什么问题,把age改为公有成员变量,还会有问题吗?编程试试看。

2、声明一个基类BaseClass,有整型成员变量Number,构造其派生类DerivedClass,观察构造函数和析构函数的执行情况。

3、声明一个车(vehicle)基类,具有Maxspeed,Weight等成员变量,Run、Stop等成员函数,由此派生出自行车(bicycle)类,汽车(motorcar)类。自行车(bicycle)类有高度(Height)等属性,汽车(motorcar)类有座位数(SeatNum)等属性。从bicycle和motorcar派生出摩托车(motorcycle)类,在继承过程中,注意把vehicle设置为虚基类。如果不把vehicle设置为虚基类,会有什么问题?编程试试看。

 

 

三、实验步骤及内容

实验1. 实现基类Animal,派生类的dog的定义声明

1.1代码及注释说明

//ageaprivateº

#include <iostream>

#include <string>

using namespace std;

 

classAnimal

{

private:

    int age;

};

class dog:public Animal

{

public:

    void SetAge(int n)

    {

         age=n;

    }

 

}

问题:age无法访问

 

 

//agepublic

#include <iostream>

#include <string>

using namespace std;

 

classAnimal

{

public:

    int age;

    voidshowage()

    {

         cout<<age<<endl;

    }

};

class dog:public Animal

{

public:

    void SetAge(int n)

    {

         age=n;

    }

};

 

intmain()

{

    dog b;

    b.SetAge(3);

    b.showage();

    return 0;

}

 

问题解决

 

1.2解析(算法设计思路,程序逻辑,流程图)

 

1.3运行结果及分析(测试用例,结果,截图,分析)

 

1.4故障和失败原因

结果截图(只保留有效内容)

 

原因及解决方案:dog类的大括号后忘记加分号,补上分号后问题解决

实验2. 实现基类BaseClass,派生类的DerivedClass的定义声明,观察构造函数和析构函数的执行情况。

    

2.1代码

#include<iostream>

#include<string>

usingnamespace std;

 

classBaseClass //基类

{

public:

    BaseClass()//默认构造函数

    {

         Number=0;//number初始为0

         cout<<"BaseClass's defaultconstructor is called"<<endl;

    }

    BaseClass(int n)//带参数的构造函数

    {

         Number=n;//输入的n赋值给number

         cout<<"BaseClass's  constructor is called"<<endl;

    }

    ~BaseClass() //析构函数

    {

         cout<<"BaseClasaas'sdestructor is called"<<endl;

    }

    void GetNumber()//输出成员数据number

    {

         cout<<Number<<endl;

    }

private:

    int Number;

   

};

classDerivedClass:public BaseClass //派生类

{

public:

    DerivedClass() //默认构造函数

    {

         c=0;

         cout<<"DerivedClass'sdefault constructor is called"<<endl;

    }

    DerivedClass(int a,int b):BaseClass(a)//带参数的构造函数,第一个参数a传给继承下来的基类数据成员number

    {

         c=b;

         cout<<"DerivedClass's  constructor is called"<<endl;

    }

    ~DerivedClass()//析构函数

    {

         cout<<"DerivedClass'sdestructor is called"<<endl;

    }

    void Getc()//输出继承的基类数据成员Nummber和自己的数据成员c

    {

         GetNumber();

         cout<<c<<endl;

   

    }

private:

    int c;

 

};

 

intmain()

{

    DerivedClass class1;//定义DerivedClass类对象 class1,不给参数,调用默认构造函数

    class1.Getc() ;

    DerivedClass class2(1,2);// 定义DerivedClass类对象 class2

    class2.Getc();

    return 0;

}

 

2.2解析(算法设计,程序逻辑,流程图)

(1).声明定义基类BaseClass

       定义实现其构造函数,析构函数。

声明数据成员Number。

       声明定义成员函数GetNumber();用以输出Number

(2).声明定义派生类DerivedClass(继承方式为public)

       定义实现其构造函数,析构函数。

声明数据成员c

声明定义成员函数Getc();用以输出c

       (3)主函数中定义DerivedClass类对象 class1,class2(1,2)

并分别调用其成员函数Getc

(4)观察结果.

2.3运行结果及分析(测试用例,结果,截图,分析)

 

第一、   二行:定义class1后,由于没有给参数。调用基类默认构造函数和派生类默认构造函数。

第二、   四行:由于在两个类的默认构造函数中,默认给数据成员Number和c赋值为0,所以调用Getc()后,输出两个0

第五、六行:定义 class2(1,2)。调用构造函数时输出提示语句

第七、八行:输出class2的Number和c的值

第九—十二行:调用析构函数(与调用构造函数的顺序相反)

2.4故障和失败原因

结果截图(只保留有效内容),并加以说明故障的原因以及解决方法

问题截图:

错误提示

 

问题代码

 

    原因:定义对象时出错。

解决方法

    DerivedClass class1();改为DerivedClass class1;

实验3. 声明一个车(vehicle)基类,具有Maxspeed,Weight等成员变量,Run、Stop等成员函数,由此派生出自行车(bicycle)类,汽车(motorcar)类。自行车(bicycle)类有高度(Height)等属性,汽车(motorcar)类有座位数(SeatNum)等属性。       

3.1代码

#include <iostream>

#include <string>

using namespace std;

 

class vehicle//定义虚基类vehicle

{

public:

       vehicle()//默认构造函数

       {

              cout<<"vehicle'sdefault constructor is called"<<endl;

              Maxspeed=0;

              Weight=0;

       }

       ~vehicle()//析构函数

       {

              cout<<"vehicle'sdestructor is called"<<endl;

       };

       void SetV(float a,floatb)//改变maxspeed和weight的函数

       {

              Maxspeed=a;

              Weight=b;

       }

       void run()

       {

              cout<<"caris running"<<endl;

       }

       void stop()

       {

              cout<<"caris stopping"<<endl;

       }

       void GetMaxspeed()//输出最大速度

       {

              cout<<"Maxspeed="<<Maxspeed<<endl;

       }

       void GetWeight()//输出重量

       {

              cout<<"Weight="<<Weight<<endl;     

       }

private:

       float Maxspeed,Weight;

};

 

 

 

class bicycle:virtual public vehicle

{

public:

       bicycle()//默认构造函数

       {

              Height=0;

              cout<<"bicycle'sdefault constructor is called"<<endl;

       }

       ~bicycle()//析构函数

       {

              cout<<"bicycle'sdestructor is called"<<endl;

       }

       void SetHeight(floata)//设置高度

       {

              Height=a;

       }

       void GetHeight()

       {

              cout<<"Height="<<Height<<endl;

       }

private:

       float Height;

};

 

class motorcar:virtual public vehicle

{

public:

       motorcar()//默认构造函数

       {

              cout<<"motorcar'sdefault constructor is called"<<endl;

              SeatNum=0;

       }

       ~motorcar()//析构函数

       {

              cout<<"motorcar'sdestructor is called"<<endl;

       }

       void SetSeatNum(int a)//设置座位个数

       {

              SeatNum=a;

       }

       void GetSeatNum()

       {

              cout<<"SeatNum="<<SeatNum<<endl;

       }

private:

       int SeatNum;

      

};

class motorcycle:public bicycle,public motorcar

{

public:

       motorcycle()//默认构造函数

       {

              cout<<"motorcycle'sdefault constructor is called"<<endl;

              cost=0;

       }

       ~motorcycle()

       {

              cout<<"motorcycle'sdestructor is called"<<endl;

       }

       void SetCost(float a)//设置花费的函数

       {

              cost=a;

       }

       void showcost()

       {

              cout<<"Cost="<<cost<<endl;

       }

      

private:  

       int cost;

};

 

int main()

{

       motorcycle Mymotorcycle;

       Mymotorcycle.SetV(100,200);//设置 maxspeed和weight分别为00,200

       Mymotorcycle.SetHeight(300);//设置height为100 

       Mymotorcycle.SetSeatNum(2);//设置座位个数为2; 

       Mymotorcycle.SetCost(520.11);//设置cost为520.11

       Mymotorcycle.GetMaxspeed();//输出GetMaxspeed

       Mymotorcycle.GetWeight();//输出weight

       Mymotorcycle.GetSeatNum();//输出座位数

       Mymotorcycle.showcost();//输出cost

       return 0;

}

3.2解析(算法设计,程序逻辑,流程图)

(1)声明一个车(vehicle)基类,具有Maxspeed,Weight等成员变量,Run、Stop等成员函数。定义改变成员变量的函数和输出成员变量的函数。

(2)由车(vehicle)基类派生出自行车(bicycle)类,汽车(motorcar)类。自行车(bicycle)类有高度(Height)等属性,汽车(motorcar)类有座位数(SeatNum)等属性。定义改变成员变量的函数和输出成员变量的函数。

(3) 从bicycle和motorcar派生出摩托车(motorcycle)类,具有成员变量cost,以及改变成员变量的函数和输出成员变量的函数。

(4)在主函数中,定义motorcycle类对象Mymotorcycle。通过调用在直接基类和间接基类里定义的函数,设置和输出成员变量Maxspeed,Weight,SeatNum,Cost。

(5)观察结果

3.3运行结果及分析(测试用例,结果,截图,分析)

 

3.4故障和失败原因

结果截图(只保留有效内容),并加以说明故障的原因以及解决方法

 

故障原因:没有把vehicle设置为虚基类,导致出现二义性问题,大批报错。

解决方法,将vehicle设置为虚基类。

即将bicycle类和motorcar类的定义语句修改如下:

class bicycle:virtual public vehicle

class motorcar:virtual public vehicle

同时删去之前定义的带参数的构造函数(可以有不删的方法,但这次没有去实现)

 

  • 19
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1 、先定义一个学生类student,其私有成员分别为(学号、生名、性别)3个,再定义一个研究生类graduate(私有成员分别为:学号、生名、性别、年龄、地址)5个。其中研究生类从学生类继承过来,分别采用公有继承与私有继承、保护继承三种方式,程序中包括输入数据的函数,运行时输入其5项的值,程序应输出5个数据值。 答案:略 2、(1) 声明一个基类Animal,有私有整型成员变量age,构造其派生类dog,在其成员函数SetAge(int n)中直接给age赋值,看看会有什么问题,把age改为公有成员变量,还会有问题吗?编程试试看。 (2) 声明一个基类BaseClass,有整形成员变量Number,构造其派生类DerivedClass,观察构造函数和析构函数的执行情况。 (3) 声明一个车(vehicle)基类,具有MaxSpeed,Weight等成员变量,Run,Stop等成员函数,由此派生出自行车(bicycle)类,汽车(motorcar)类。自行车(bicycle)类有高度(Height)等属性,汽车(motorcar)类有座位数(SeatNum)等属性。从bicycle和motorcar派生出摩托车(motocycle)类,在继承过程中,注意把vehicle设置为虚基类。如果不把vehicle设置为虚基类,会有什么问题?编程试试看。 (4)(选做)从people(人员)类派生出student(学生)类,添加属性:班号 char classNo[7];从people类派生出teacher(教师)类,添加属性:职务char principalship[11]、 部门char department[21]。从student类中派生出graduate(研究生)类,添加属性:专业char subject[21]、导师teacherradviser;从graduate类和teacher类派生出TA(助教生)类,注意虚基类的使用。重载相应的成员函数,测试这些类。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值