}
实验四、类与对象(2学时)
1、实验目的:
掌握类的定义和使用
掌握类的定义和对象的声明
复习具有不同访问属性的成员的访问方式。
察构造函数和析构函数的执行过程。
学习类的聚集使用方法。
使用DEBUG来调试程序,跟踪观察类的构造函数、析构函数、成员函数的执行顺序。
2、实验任务
1)定义一个CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等属性,有两个公有成员函数run、stop。
其中rank为枚举类型CPU_Rank,定义为enumCPU_Rank={P1=1,P2,P3,P4,P5,P6,P7},frequency为单位为MHz的整型数,voltage为浮点型的电压值。
观察构造函数和析构函数的调用顺序。
2)定义一个简单的Computer类,有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,cpu为CPU类的一个对象,ram为RAM类的一个对象,cdrom为CDROM类的一个对象,定义并实现这个类。
3、实验步骤与结果
首先定义枚举类型CPU_Rank,例如enumCPU_Rank{P1=1,P2,P3,P4,P5,P6,P7},再定义CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等私有数据成员,定义成员函数run、stop,用来输出提示信息,在构造函数和析构函数中也可以输出提示信息。
在主程序中定义一个CPU类的对象,调用其成员函数,观察类对象的构造与析构顺序,以及成员函数的调用。
程序名:
lab4_1.cpp。
使用debug调试功能观察lab4_1.cpp的运行流程,跟踪观察类的构造函数、析构函数、成员函数的执行顺序。
参考程序如下:
(3)调试操作步骤如下:
Build|StartDebug|StepInto命令,系统进行单步执行状态,程序开始运行,一个DOS窗口出现,此时光标停在main()函数的入口处;
A)从Debug菜单栏中单击StepOver,此时,光标下移,程序准备执行CPU对象的初始化;
B)单击StepInto,程序准备执行CPU类的构造函数;
C)连续单击StepOver,观察构造函数的执行情况,直到执行完构造函数,程序回到主函数;
D)此时程序准备执行CPU对象的run()函数,单击StepInto,程序进入run()成员函数,连续单击StepOver,直到回到main()函数;
E)继续执行程序,参照上述的方法,观察程序的执行顺序,加深对类的构造函数、析构函数、成员函数的执行顺序的认识;
F)再试Debug菜单栏中的别的菜单项,熟悉Debug的各种方法。
G)选定义CPU类、RAM类、CDROM类。
再定义Computer类:
定义私有数据成员cpu、ram、cdrom,定义公有成员函数run、stop,可在其中输出提标信息居主程序中定义一个Computer的对象,调用其成员函数,观察类对象及其成员变量的构造与析构顺序,以及成员函数的调用。
程序名:
lab4_2.cpp。
(5)使用debug调试功能观察lab4_2.cpp程序的运行流程,跟踪观察类的构造函数、析构函数、成员函数的执行顺序,特别注意观察成员变量的构造与析构顺序。
4、实验原理
类的引入、定义和使用
类的嵌套使用
构造函数与析构函数的作用即执行时段
枚举类型的用法
Visualc++调试工具的使用
5、思考与体会
C++是面向对象的一种计算机语言,虽然与C语言有着很大的关系,但是于面向过程的C,还是有不同,比如引入了类这一概念。
类类似于C语言中的结构体,但又与结构体有区别。
类是抽象得到的数据和行为的封装,在C++中是一个基础的成员。
6、部分参考代码
Lab4_1
#include
enumRank{p1=1,p2,p3,p4,p5,p6,p7};
//CPU类
classCPU{
public:
Rankrank;
intfrequency;
floatvoltage;
CPU(Rankr,intf,floatv){//构造函数
cout<<"构造了一个CPU"<rank=r;
frequency=f;
voltage=v;
}
voidrun(){
cout<<"CPU开始运行"<}
voidstop(){
cout<<"CPU停止运行"<}
voidshow(){
cout<<"RANK="<cout<<"frequency="<cout<<"voltage="<}
~CPU(){cout<<"析构函数";}//析构函数
};
intmain(){
CPUcpu(p5,500,2000);
cpu.run();
cpu.show();
cpu.stop();
return0;
}
Lab4_2
#include
usingnamespacestd;
enumRank{p1=1,p2,p3,p4,p5,p6,p7};
//CPU类
classCPU{
public:
Rankrank;
intfrequency;
floatvoltage;
CPU(Rankr,intf,floatv){
cout<<"构造了一个CPU"<rank=r;
frequency=f;
voltage=v;
}
voidrun(){
cout<<"CPU开始运行"<}
voidstop(){
cout<<"CPU停止运行"<}
voidshow(){
cout<<"RANK="<cout<<"frequency="<cout<<"voltage="<}
~CPU(){cout<<"cpu析构函数"<};
//RAM类
classRAM{
public:
RAM(inti=0){cout<<"构造了一个RAM"<~RAM(){cout<<"Ram析构函数"<};
//CDROM类
classCDROM{
public:
CDROM(inti=0){cout<<"构造了一个CDRAM"<~CDROM(){cout<<"CDRam析构函数"<};
//computer类
classcomputer{
public:
computer(Rankr,intf,floatv){
CPUcpu(r,f,v);//定义CPU对象
RAMram
(1);//定义RAM对象
CDROMcdrom
(1);//定义CDROM对象
cpu.run();
cpu.show();
cpu.stop();
}
};
intmain(){
computercom(p4,300,3000);
return0;
}
实验七、继承与派生(一、二)4学时
1、实验目的:
学习定义和使用类的继承关系,定义派生类。
熟悉不同继承方式下对基类成员的访问控制。
学习利用虚基类解决二义性问题
2、实验任务
a)定义一个基类Animal,有私有整型成员变量age,构造其派生类dog,在其成员函数SetAge(intn)中直接给age赋值,看看会有什么问题,把age改为公有成员变量,还会有问题吗?
编程试试看。
b)定义一个基类BaseClass,有整型成员变量Number,构造其派生类DerivedClass,观察构造函数和析构函数的执行情况。
c)定义一个车(vehicle)基类,具有MaxSpeed、Weight等成员变量,Run、Stop等成员函数,由此派生出自行车(bicycle)类、汽车(motorcar)类。
自行车类有高度(height)等属性,汽车类有座位数(SeatNum)等属性。
从bicycle和motorcar派生出摩托车(motorcycle)类,在继承过程中,注意把vehicle设置为虚基类。
如果不把vehicle设置为虚基类,会有什么问题?
编程试试看。
3、实验步骤
编写程序定义基类Animal,成员变量age定义为私有的。
构造派生类dog,在其成员函数SetAge(intn)中直接对age赋值时,会出现类似以下的错误提示:
errorC2248:
’age’:
cannotaccessprivatememberdeclaredinclass‘Animal’
errorC2248:
’age’:
cannotaccessprivatememberdeclaredinclass‘Animal’
把age改为公有成员变量后重新编译就可以了。
程序名为:
lab7_1.cpp
(2)编写程序定义一个基类BassClass,构造其派生类DerivedClass,在构造函数和析构函数中用cout输出提示信息,观察构造函数和析构函数的执行情况。
程序名为:
lab7_2.cpp。
4、实验原理
C++语序一个基类衍生出多个派生类,也允许一个派生类继承多个父类
派生类中可以调用父类的的Public和protect成员,但不能直接调用基类的private成员
对于构造函数,先调用父类的构造函数,在调用子类的。
析构函数的调用则相反
5、思考与体会
对于一个派生类有众多的基类是C++继承方面的一个特殊之处,别的面向对象语言像Java都是不允许的。
C++的这种允许有时的确方便我们编程。
6、部分参考代码
Lab7_1
#include
usingnamespacestd;
classAnimal{
public:
intage;
};
classdog:
publicAnimal{
public:
intSetAge(intn){
age=n;
returnage;
}
};
voidmain(void){
intage;
dogd;
age=d.SetAge(3);
cout<<"age="<}
Lab7_2
#include
usingnamespacestd;
classBaseClass{
public:
intNumber;
BaseClass(){
cout<<"这是父类的构造函数"<}
~BaseClass(){
cout<<"这是父类的析构函数"<}
};
classDerivedClass:
publicBaseClass{
public:
DerivedClass(inti=0){
cout<<"这是子类的构造函数"<}
~DerivedClas