C第5章习题参考答案Word格式.docx
《C第5章习题参考答案Word格式.docx》由会员分享,可在线阅读,更多相关《C第5章习题参考答案Word格式.docx(26页珍藏版)》请在冰豆网上搜索。
这样派生类中的其它成员函数均无权访问它,外界不可能通过派生新类来达到访问基类私有成员的目的。
4.派生类构造函数和析构函数的执行顺序是怎样的?
在多继承中,派生类构造函数和析构函数的执行顺序又是怎样的?
构造函数的执行顺序:
先祖先(基类)、再客人(对象成员),后自己(派生类本身)。
析构函数的执行顺序和构造函数正好严格相反:
先自己(派生类本身),再客人(对象成员),后祖先(基类)。
在多个基类之间严格按照派生类定义时从左到右的顺序来排列先后。
而析构函数的调用顺序刚好与构造函数的相反。
5.派生类的构造函数和析构函数的作用是什么?
在下面两种情况下,必须定义派生类的构造函数:
派生类本身需要构造函数;
在定义派生类对象时,其相应的基类对象需调用带有参数的构造函数。
派生类对象的初始化也是通过派生类的构造函数实现的。
具体来说,就是对该类的数据成员赋初值。
派生类析构函数的功能与没有继承关系的类中析构函数的功能一样,也是在对象消亡之前进行一些必要的清理工作。
6.多继承一般应用在哪些场合?
对于多重继承,派生类可以有多个直接基类。
这时的派生类同时得到了多个已有类的特征。
7.在类的派生中为何引入虚基类?
在含有虚基类的派生类中,当创建它的对象时,构造函数的执行顺序如何?
当在多条继承路径上有一个公共的基类,在这些路径中的某几条路径汇合处,这个公共的基类就会产生多个实例(或多个副本),若想只保存这个基类的一个实例,可以将这个公共基类说明为虚基类。
从基类派生新类时,使用关键字virtual可以将基类说明成虚基类。
在多个基类之间严格按照派生类定义时从左到右的顺序来排列先后。
如果基类中有虚基类,则构造函数的调用顺序采用下列规则:
(1)虚基类的构造函数在非虚基类之前调用。
(2)若同一层次中包含多个虚基类,这些虚基类的构造函数按照他们说明的次序调用;
(3)若虚基类由非虚基类派生而来,则仍然先调用基类构造函数,再调用派生类的构造函数。
特别需要注意,当一个派生类同时有多个基类时,对于所有需要给予参数进行初始化的基类,都要显式给出基类名和参数表。
对于使用默认构造函数的基类,可以不给出类名。
同样,对于对象成员,如果是使用默认构造函数,也不需要写出对象名和参数表。
而对于单继承,就只需要写一个基类名就可以了。
8.设计一个大学的类系统,学校中有学生、教师、职员,每种人员都有自己的特性,他们之间又有相同的地方。
利用继承机制定义这个系统中的各个类及类上必须的操作。
参考程序:
#include<
iostream.h>
string.h>
classPerson{
protected:
charm_strName[10];
intm_nSex;
intm_nAge;
public:
Person(char*name,intage,charsex){
strcpy(m_strName,name);
m_nSex=(sex=='
m'
?
0:
1);
m_nAge=age;
}
voidsetName(char*name){
voidsetSex(intsex){
voidsetAge(intage){
char*getName(){
returnm_strName;
intgetAge(){
returnm_nAge;
intgetSex(){
returnm_nSex;
voidShowMe(){
cout<
<
"
姓名:
m_strName<
endl;
性别:
(m_nSex==0?
男"
:
女"
)<
年龄:
m_nAge<
};
classTeacher:
publicPerson{
charm_strDept[20];
intm_fSalary;
Teacher(char*name,intage,charsex,char*dept,intsalary)
:
Person(name,age,sex){
strcpy(m_strDept,dept);
m_fSalary=salary;
voidShowMe(){
Person:
ShowMe();
工作单位:
m_strDept<
月薪:
m_fSalary<
voidsetSalary(intsalary){
m_fSalary=salary;
intgetSalary(){
returnm_fSalary;
classStudent:
charm_strID[12];
charm_strClass[12];
Student(char*name,intage,charsex,char*ID,char*Class)
strcpy(m_strID,ID);
strcpy(m_strClass,Class);
学号:
m_strID<
班级:
m_strClass<
\n"
;
voidsetID(char*ID){
voidsetClass(char*Class){
char*getID(){
returnm_strID;
char*getClass(){
returnm_strClass;
classEmployee:
publicPerson{
Employee(char*name,intage,charsex,intsalary)
工资:
voidmain(){
//定义三个不同类的对象
Teacherteacher1("
刘馨"
38,'
"
计算机系"
3800);
Studentstd1("
刘丽"
20,'
f'
计算机03"
);
EmployeeemPloyee1("
张鑫"
25,'
1500);
//显示各类人员的属性
teacher1.ShowMe();
cout<
--------------------"
std1.ShowMe();
emPloyee1.ShowMe();
//修改各类人员的属性
teacher1.setAge(40);
teacher1.setSalary(4500);
std1.setAge(21);
emPloyee1.setAge(26);
emPloyee1.setSalary(2000);
修改各类人员的属性后:
}
程序的执行结果为:
姓名:
刘馨
男
38
计算机系
3800
-------------------
刘丽
女
20
计算机03
张鑫
25
1500
40
4500
21
26
2000
9.假定车可分为货车和客车,客车又可分为轿车、面包车和公共汽车。
请设计相应的类层次结构。
可以把轿车、面包车和公共汽车定义为客车类的对象
#include<
iostream>
usingnamespacestd;
classvehicle//定义基类vehicle
{
//公有函数成员
vehicle(intin_wheels,floatin_weight);
//给数据成员初始化
intget_wheels();
//获取车轮数
floatget_weight();
//获取汽车重量
voidsetWeels(intwls);
voidsetWeight(floatwt);
voiddisplay(){
车轮数:
wheels
<
汽车重量:
weight<
private:
//私有数据成员
intwheels;
//车轮数
floatweight;
//表示汽车承重
vehicle:
vehicle(intin_wheels,floatin_weight){
wheels=in_wheels;
weight=in_weight;
floatvehicle:
get_weight(){
returnweight;
intvehicle:
get_wheels(){
returnwheels;
voidvehicle:
setWeels(intwls){
wheels=wls;
setWeight(floatwt){
weight=wt;
classtruck:
publicvehicle//定义货车类truck
//新增私有数据成员
floatweight_load;
//承重
//新增公有成员函数
truck(intwheel,floatwt,floatwl):
vehicle(wheel,wt){
weight_load=wl;
floatgetLoads(){
returnweight_load;
vehicle:
display();
汽车承重"
weight_load<
//车和客车,客车又可分为轿车、面包车和公共汽车
classcar:
publicvehicle//定义客车类car
intpassenger_load;
//新增私有数据成员,表示载客数
//新增公有成员函数
car(intin_wheels,floatin_weight,intpeople=4):
vehicle(in_wheels,in_weight)
{
passenger_load=people;
intgetPassengers(){
returnpassenger_load;
voidsetPassengers(intpeople){
载客数:
passenger_load<
trucktruck1(8,400,);
//货车
carcar1(4,20);
//客车
carsaloon_car(4,10,5);
//轿车
carmicrobus(6,10,18);
//面包车
carbus(6,20,30);
//公共汽车
//显示相关信息
truck1.display();
---------------------"
car1.display();
saloon_car.display();
microbus.display();
bus.display();
程序的运行结果:
8汽车重量:
400
汽车承重
---------------------
4汽车重量:
4
10
5
6汽车重量:
18
30
10.设计一个能细分为矩形、三角形、圆形和椭圆形的“图形”类。
使用继承将这些图形分类,找出能作为基类部分的共同特征(如宽、高、中心点等)和方法(如初始化、求面积等),并看看这些图形是否能进一步划分为子类。
classFigure//定义基类图形类
Figure(intwid){width=wid;
floatarea(){}
intgetWidth(){returnwidth;
intwidth;
//宽度或半径
classRectangle:
publicFigure{//定义矩形类
intheight;
Rectangle(intwid,inthei):
Figure(wid){
height=hei;
floatarea(){returngetWidth()*height;
classTriangle:
publicFigure{//定义三角形类
intheight;
Triangle(intwid,inthei):
floatarea(){return1.0/2*getWidth()*height;
classCircle:
publicFigure{//定义圆类
Circle(intwid):
floatarea(){return3.14*getWidth()*getWidth();
Rectanglerect(5,4);
Triangletri(5,4);
Circlecir(5);
矩形的面积是:
rect.area()<
endl
<
三角形的面积是:
tri.area()<
圆的面积是:
cir.area()<
程序的运行结果为:
78.5
11.考虑大学的学生情况,试利用单继承来实现学生和毕业生两个类,设计相关的数据成员及函数,编程对继承情况进行测试。
classStudent//定义基类vehicle
Student(intn,char*na,intg):
number(n),grade(g){
strcpy(name,na);
intgetNumber(){
returnnumber;
returnname;
intgetGrade(){
returngrade;
学号:
number<
姓名:
name<
年级:
grade<
intnumber;
//学号
charname[20];
//姓名
intgrade;
//年级
classGraduate:
publicStudent{//定义毕业生类
chardesignSubject[20];
Graduate(intn,char*na,char*deSub,intg=4):
Student(n,na,g)
{strcpy(designSubject,deSub);
Student:
设计题目:
designSubject<
//创建对象
Studentli(2,"
LiMing"
3);
Graduatezhang(3,"
ZhangGang"
学生成绩管理系统"
//显示对象的相关信息
li.display();
cout<
endl<
-----------------------------------"
<
zhang.display();
2
LiMing
3
-----------------------------------
ZhangGang
学生成绩管理系统
12.定义一个哺乳动物类,再由此派生出人类、狗类和猫类,这些类中均有speak()函数,观察在调用过程中,到底使用了谁的speak()函数。
classAnimal{
voidspeak(){}
voidsetWeight(floatwt){weight=wt;
floatgetWeight(){returnwei