最新C++语言程序设计实验答案继承与派生资料.docx
《最新C++语言程序设计实验答案继承与派生资料.docx》由会员分享,可在线阅读,更多相关《最新C++语言程序设计实验答案继承与派生资料.docx(20页珍藏版)》请在冰豆网上搜索。
最新C++语言程序设计实验答案继承与派生资料
实验07继承与派生(4学时)
(第7章继承与派生)
一、实验目的
(1)学习声明和使用类的继承关系,声明派生类。
(2)熟悉不同继承方式下对基类成员的访问控制。
(3)学习利用虚基类解决二义性问题。
二、实验任务
7_1声明一个基类Animal。
有私有整型成员变量age,构造其派生类dog,在其成员函数SetAge(intn)中直接给age赋值,看看会有什么问题,把age改为公有成员变量,还会有问题吗?
编程试试看。
7_2声明一个基类BaseClass。
有整型成员变量Number,构造其派生类DerivedClass,观察构造函数和析构函数的执行情况。
7_3声明一个车(vehicle)基类。
具有MaxSpeed、Weight等成员变量,Run、Stop等成员函数,由此派生出自行车(bicycle)类、汽车(motorcar)类。
自行车(bicycle)类有高度(Height)等属性,汽车(motorcar)类有座位数(SeatNum)等属性。
从bicycle和motorcar派生出摩托车(motorcycle)类,在继承过程中,注意把vehicle设置为虚基类。
如果不把vehicle设置为虚基类,会有什么问题?
编程试试看。
7_4以实验6中的People(人员)类为基类。
派生出student(学生)类,添加属性:
班号charclassNo[7];
派生出teacher(教师)类,添加属性:
职务charprincipalship[11]、部门chardepartment[21]。
从student类中派生出graduate(研究生)类,添加属性:
专业charsubject[21]、导师teacheradviser;
从graduate类和teacher类派生出TA(助教生)类,注意虚基类的使用。
重载相应的成员函数,测试这些类。
类之间的关系如图7-1所示。
图7-1类图
三、实验步骤
1.(编程)声明基类Animal,成员变量age声明为私有的。
构造派生类dog,在其成员函数SetAge(intn)中直接对age赋值时,会出现类似以下的错误提示:
(注:
在桌面创建一个文本文件,将输出框的内容复制到文本文件中,再复制到Word文件中,不会出现汉字的乱码)
用private时的结果:
1>------已启动生成:
项目:
cpp,配置:
DebugWin32------
1>生成启动时间为2013-2-1811:
10:
35。
1>InitializeBuildStatus:
1>正在创建“Debug\cpp.unsuccessfulbuild”,因为已指定“AlwaysCreate”。
1>ClCompile:
1>main.cpp
1>f:
\projects\cpp\cpp\main.cpp(13):
errorC2248:
“Animal:
:
age”:
无法访问private成员(在“Animal”类中声明)
1>f:
\projects\cpp\cpp\main.cpp(8):
参见“Animal:
:
age”的声明
1>f:
\projects\cpp\cpp\main.cpp(5):
参见“Animal”的声明
1>f:
\projects\cpp\cpp\main.cpp(14):
errorC2248:
“Animal:
:
age”:
无法访问private成员(在“Animal”类中声明)
1>f:
\projects\cpp\cpp\main.cpp(8):
参见“Animal:
:
age”的声明
1>f:
\projects\cpp\cpp\main.cpp(5):
参见“Animal”的声明
1>
1>生成失败。
1>
1>已用时间00:
00:
03.28
==========生成:
成功0个,失败1个,最新0个,跳过0个==========
把age改为公有变量后重新编译就可以了。
程序名:
lab7_1.cpp。
★程序及运行结果:
//lab7_1.cpp
#include
usingnamespacestd;
classAnimal{
private:
//private时出错
//public:
//public和protected正确
intage;
};
classdog:
publicAnimal{
public:
voidSetAge(intn){age=n;}
intGetAge(){returnage;}
};
voidmain()
{dogd;d.SetAge(3);cout<<"Age="<用private时的结果:
1>------已启动生成:
项目:
cpp,配置:
DebugWin32------
1>生成启动时间为2013-2-1811:
10:
35。
1>InitializeBuildStatus:
1>正在创建“Debug\cpp.unsuccessfulbuild”,因为已指定“AlwaysCreate”。
1>ClCompile:
1>main.cpp
1>f:
\projects\cpp\cpp\main.cpp(13):
errorC2248:
“Animal:
:
age”:
无法访问private成员(在“Animal”类中声明)
1>f:
\projects\cpp\cpp\main.cpp(8):
参见“Animal:
:
age”的声明
1>f:
\projects\cpp\cpp\main.cpp(5):
参见“Animal”的声明
1>f:
\projects\cpp\cpp\main.cpp(14):
errorC2248:
“Animal:
:
age”:
无法访问private成员(在“Animal”类中声明)
1>f:
\projects\cpp\cpp\main.cpp(8):
参见“Animal:
:
age”的声明
1>f:
\projects\cpp\cpp\main.cpp(5):
参见“Animal”的声明
1>
1>生成失败。
1>
1>已用时间00:
00:
03.28
==========生成:
成功0个,失败1个,最新0个,跳过0个==========
用public时的结果:
2.(编程)声明一个基类BaseClass,构造其派生类DerivedClass。
在构造函数和析构函数中用cout输出提示信息,观察构造函数和析构函数的执行情况。
程序名:
lab7_2.cpp。
参考的运行结果:
★程序及运行结果:
//lab7_2.cpp
#include
usingnamespacestd;
classBaseClass{
public:
BaseClass(){cout<<"构造了一个BaseClass类的对象."<~BaseClass(){cout<<"析构了一个BaseClass类的对象."<private:
intNumber;
};
classDeriveClass:
publicBaseClass{
public:
DeriveClass(){cout<<"构造了一个DeriveClass类的对象."<~DeriveClass(){cout<<"析构了一个DeriveClass类的对象."<};
voidmain()
{DeriveClassa;}
3.(操作)用调试功能跟踪程序lab7_2的执行过程。
观察基类和派生类的构造函数和析构函数的执行情况。
4.(编程)声明一个车(vehicle)虚基类。
由此派生出自行车(bicycle)类、汽车(motorcar)类,注意把vehicle派生为虚基类。
再从bicycle和motorcar派生出摩托车(motorcycle)类,在main()函数中测试这个类。
程序名:
lab7_3.cpp。
参考的运行结果:
★程序及运行结果:
//lab7_3.cpp
#include
usingnamespacestd;
classvehicle{//车类,作为基类
protected:
intMaxSpeed,Weight;//最大速度,重量
public:
voidRun(){cout<<"车vehicle类开始运行!
"<voidStop(){cout<<"车vehicle类停止运行!
"<};
classbicycle:
virtualpublicvehicle{//自行车类:
公有继承虚基类vehicle
protected:
intHeight;//高度
};
classmotorcar:
virtualpublicvehicle{//汽车类:
公有继承虚基类vehicle
protected:
intSeatNum;//座位数
};
classmotorcycle
:
publicbicycle,publicmotorcar{//摩托车类:
公有继承自行车类和汽车类
public:
voidSetdata(intms,intwt,intht,intsn)
{MaxSpeed=ms;Weight=wt;Height=ht;SeatNum=sn;};
voidShow(){
cout<<"最大速度:
"<"<<<"高度:
"<"<}
};
voidmain(){
cout<<"int类型占用字节数:
"<cout<<"vehicle占用字节数:
"<cout<<"bicycle占用字节数:
"<cout<<"motorcar占用字节数:
"<cout<<"motorcycle占用字节数:
"<motorcyclemt;
mt.Run();
mt.Setdata(100,200,130,2);
mt.Show();
mt.Stop();
}
为什么?
按推算应该是:
vehicle占用8字节;
bicycle占用12字节;
motorcar占用12字节;
motorcycle占用16字节。
5.(验证)把vehicle设置为非虚基类。
再编译一次,此时系统报错,无法编译成功。
这是因为若不把vehicle设置为虚基类,会出现二义性错误,程序不能成功编译。
访问vehicle的成员时指明继承路径后,可以纠正二义性错误,试修改程序,然后运行。
★程序的运行结果:
(1)没有指明继承路径(运行结果)
将上面的程序的bicycle类和motorcar类改为非虚基类公有继承vehicle类后,编译时出现二义(ambiguous)性错误:
1>------已启动生成:
项目:
cpp,配置:
DebugWin32------
1>生成启动时间为2013-2-1811:
23:
32。
1>InitializeBuildStatus:
1>正在创建“Debug\cpp.unsuccessfulbuild”,因为已指定“AlwaysCreate”。
1>ClCompile:
1>main.cpp
1>f:
\projects\cpp\cpp\main.cpp(27):
errorC2385:
对“MaxSpeed”的访问不明确
1>可能是“MaxSpeed”(位于基“vehicle”中)
1>也可能是“MaxSpeed”(位于基“vehicle”中)
1>f:
\projects\cpp\cpp\main.cpp(27):
errorC2385:
对“Weight”的访问不明确
1>可能是“Weight”(位于基“vehicle”中)
1>也可能是“Weight”(位于基“vehicle”中)
1>f:
\projects\cpp\cpp\main.cpp(29):
errorC2385:
对“MaxSpeed”的访问不明确
1>可能是“MaxSpeed”(位于基“vehicle”中)
1>也可能是“MaxSpeed”(位于基“vehicle”中)
1>f:
\projects\cpp\cpp\main.cpp(30):
errorC2385:
对“Weight”的访问不明确
1>可能是“Weight”(位于基“vehicle”中)
1>也可能是“Weight”(位于基“vehicle”中)
1>f:
\projects\cpp\cpp\main.cpp(42):
errorC2385:
对“Run”的访问不明确
1>可能是“Run”(位于基“vehicle”中)
1>也可能是“Run”(位于基“vehicle”中)
1>f:
\projects\cpp\cpp\main.cpp(42):
errorC3861:
“Run”:
找不到标识符
1>f:
\projects\cpp\cpp\main.cpp(45):
errorC2385:
对“Stop”的访问不明确
1>可能是“Stop”(位于基“vehicle”中)
1>也可能是“Stop”(位于基“vehicle”中)
1>f:
\projects\cpp\cpp\main.cpp(45):
errorC3861:
“Stop”:
找不到标识符
1>
1>生成失败。
1>
1>已用时间00:
00:
01.07
==========生成:
成功0个,失败1个,最新0个,跳过0个==========
(2)指明继承路径(程序及运行结果)
将vehicle中数据成员和函数成员指明路径。
//lab7_3.cpp
#include
usingnamespacestd;
classvehicle{//车类,作为基类
protected:
intMaxSpeed,Weight;//最大速度,重量
public:
voidRun(){cout<<"车vehicle类开始运行!
"<voidStop(){cout<<"车vehicle类停止运行!
"<};
classbicycle:
publicvehicle{//自行车类:
公有继承虚基类vehicle
protected:
intHeight;//高度
};
classmotorcar:
publicvehicle{//汽车类:
公有继承虚基类vehicle
protected:
intSeatNum;//座位数
};
classmotorcycle
:
publicbicycle,publicmotorcar{//摩托车类:
公有继承自行车类和汽车类
public:
voidSetdatabicycle(intms,intwt,intht,intsn){
bicycle:
:
MaxSpeed=ms;bicycle:
:
Weight=wt;//修改,指明路径
Height=ht;SeatNum=sn;
};
voidShowbicycle(){
cout<<"最大速度:
"<:
MaxSpeed<<"重量:
"<:
Weight
<<"高度:
"<"<}
};
voidmain(){
cout<<"int类型占用字节数:
"<cout<<"vehicle占用字节数:
"<cout<<"bicycle占用字节数:
"<cout<<"motorcar占用字节数:
"<cout<<"motorcycle占用字节数:
"<motorcyclemt;
mt.bicycle:
:
Run();//修改,指明路径
mt.Setdatabicycle(100,200,130,2);
mt.Showbicycle();
mt.motorcar:
:
Stop();//修改,指明路径
}
6.以实验6中的people(人员)类为基类,派生相应的类。
按任务7_4的要求编写程序,并运行。
参考的运行结果:
★程序及运行结果:
(1)lab6_7.h:
People(人员)类的声明及成员函数的实现
//lab6_7.h
#include
#include
usingnamespacestd;
classDate{
private:
intyy,mm,dd;
public:
Date(){}
Date(Date&d):
yy(d.yy),mm(d.mm),dd(d.dd){}//增添
~Date(){}
intGetyy()const{returnyy;}
intGetmm()const{returnmm;}
intGetdd()const{returndd;}
voidSetyy(inty){yy=y;}
voidSetmm(intm){mm=m;}
voidSetdd(intd){dd=d;}
};
classPeople{
private:
charname[11];//姓名,增添
charnumber[7];//编号,改为数组
charsex[3];//男或女,改为数组
Datebirthday;//出生日期
charid[16];//身份证号,改为数组
public:
People(){}
People(People&p);
~People(){}
voidGetname(charna[]){strcpy(na,name);}
voidGetnumber(charnu[]){strcpy(nu,number);}
voidGetsex(charse[]){strcpy(se,sex);}
intGetbirthyy()const{returnbirthday.Getyy();}
intGetbirthmm()const{returnbirthday.Getmm();}
intGetbirthdd()const{returnbirthday.Getdd();}
voidGetid(chard[]){strcpy(d,id);}
voidSetname(charna[]){strcpy(name,na);}
voidSetnumber(charnu[]){strcpy(number,nu);}
voidSetsex(charse[]){strcpy(sex,se);}
voidSetbirthyy(inty){birthday.Setyy(y);}
voidSetbirthmm(intm){birthday.Setmm(m);}
voidSetbirthdd(intd){birthday.Setdd(d);}
voidSetid(chard[]){strcpy(id,d);}
voidinput();
voidoutput();
};
People:
:
People(People&p)
:
birthday(p.birthday)
{
strcpy(name,p.name);
strcpy(number,p.number);
strcpy(sex,p.sex);
strcpy(id,p.id);
}
inlinevoidPeople:
:
input()
{
cout<<"姓名:
";cin>>name;
cout<<"编号:
";cin>>number;
cout<<"性别(男/女):
";cin>>sex;
cout<<"出生日期(年月日):
";
inty,m,d;cin>>y>>m>>d;
Setbirthyy(y);Setbirthmm(m);Setbirthdd(d);
cout<<"身份证号:
";cin>>id;
}
inlinevoidPeople:
:
output()
{
cout<<"姓名:
"<"<cout<<"性别:
"<cout<<"出生日期:
"<<cout<<"身份证号:
"<}
(2)lab7_4.h:
People类的派生类
//lab7_4.h
#include"lab6_7.h"
classstudent:
virtualpublicPeople{//学生类
private:
charclassNo[7];//班号
public:
student(){}
student(student&st):
People(st){strcpy(classNo,st.classNo);}//使用类型兼容规则
~student(){}
voidGetclassNo(charcNo[]){strcpy(cNo,classNo);}
voidSetclassNo(char*c){strcpy(classNo,c);}
voidinput()
{People:
:
input();cout<<"班号:
";cin>>classNo;}
voidoutput()
{People:
:
output();cout<<"班号:
"<};
classteacher:
virtualpublicPeople{//教师类
private:
charprincipalship[11];//职务
chardepartment[21];//部门
public:
teacher(){}