第8 继承与多态习题 - noanswer
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
继承与多态习题
一.基本概念与基础知识自测题
8.1填空题
8.1.1 如果类α继承了类β,则类α称为(1)类,而类β称为(2)类。
(3)类
的对象可作为(4)类的对象处理,反过来不行,因为(5)。
如果强制转换则要注意(6)。
答案:(1)基类
(2)派生类
(3)派生类
(4)基类
(5)派生类有一些新成员
(6)只能派生类强制转换为基类
8.1.2 当用public继承从基类派生一个类时,基类的public成员成为派生类的(1)成员,
protected成员成为派生类的(2)成员,对private成员是(3)。
公有派生可以使其类的(4),所以公有派生是主流。
答案:(1)public成员
(2)protected成员
(3)不可访问
(4)接口不变
8.1.3 利用继承能够实现(1)。
这种实现缩短了程序开发的时间,VC++中的(2)很
好地体现了这一点。
答案:(1)代码的复用
(2)MFC编程
8.1.4 一个派生类只有一个直接基类的情况称为(1),而有多个直接基类的情况称为
(2)。
继承体现了类的(3)概念,这在MFC中得到了很好表现,MFC中只采用了(4)。
答案:(1)单继承
(2)多重继承
(3)层次
(4)单继承
8.1.5 C++中多态性包括两种多态性:(1)和(2)。
前者是通过(3)实现的,
而后者是通过(4)和(5)来实现的。
答案:(1)编译时的
(2)运行时的
(3)函数和运算符的重载
(4)类继承关系
(5)虚函数
8.1.6 在基类中将一个成员函数说明成虚函数后,在其派生类中只要(1)、(2)和
(3)完全一样就认为是虚函数,而不必再加关键字(4)。
如有任何不同,则认为是(5)而不是虚函数。
除了非成员函数不能作为虚函数外,(6)、(7)和(8)也不能作为虚函数。
答案:(1)同虚函数名
(2)同参数表
(3)同返回类型。
如基类中返回基类指针,而派生类中返回派生类指针是允许的
(4)virtual
(5)重载
(6)静态成员函数
(7)内联函数
(8)构造函数
8.1.7 纯虚函数定义时在函数参数表后加 (1) ,它表明程序员对函数 (2) ,其本质
是将指向函数体的指针定为 (3) 。
答案:(1)=0
(2)不定义
(3)NULL
8.2 简答题
8.2.1 构造函数和析构函数可以继承吗?派生类构造函数各部分的执行次序是怎样的? 答:构造函数和析构函数不可以继承。
派生类构造函数各部分的执行次序是:
1. 调用基类构造函数,按它们在派生类声明的先后顺序,依次调用。
2. 调用新增成员对象的构造函数,按它们在类定义中声明的先后顺序,依次调用。
3. 派生类的构造函数体中的操作。
8.2.2 什么叫派生类的同名覆盖(override )?
答:如果派生类声明了一个和某个基类成员同名的新成员(当然如是成员函数,参数表也必须一样,否则是重载),派生类中的新成员就屏蔽了基类同名成员,类似函数中的局部变量屏蔽全局变量。
称为同名覆盖(override )。
8.2.3 派生类的析构函数中需完成什么任务?是否要编写对基数和成员对象的析构函数的
调用?为什么?
答:析构函数的功能是作善后工作,析构函数无返回类型也没有参数,情况比较简单。
派生类析构函数定义格式与非派生类无任何差异,不要编写对基数和成员对象的析构函数的调用,只要在函数体内把派生类新增一般成员处理好就可以了,因为对新增的成员对象和基类的善后工作,系统会自己调用成员对象和基类的析构函数来完成。
8.2.4 为什么要使用虚基类?怎样定义虚基类?用一个实例来解释虚基类在其派生类中的
存储方式。
答:在多重继承是有可能出现同一基类的两个拷贝,为避免这种情况,可使用虚基类。
虚基类(virtual base class )定义方式如下:
class 派生类名:virtual 访问限定符 基类类名{...};
class 派生类名:访问限定符 virtual 基类类名{...};
virtual 关键字只对紧随其后的基类名起作用。
如下派生:
存储关系如(b),在职研究生类有两个Person 拷贝。
采用虚基类后存储关系如下: 在职研究生类只有一个Person 拷贝。
8.2.5 简单叙述派生类与基类的赋值兼容规则。
答:凡是基类所能解决的问题,公有派生类都可以解决。
在任何需要基类对象的地方都可以用公有派生类的对象来代替,这条规则称赋值兼容规则。
它包括以下情况: 1. 派生类的对象可以赋值给基类的对象,这时是把派生类对象中从对应基类中继承来的成员赋值给基类对象。
反过来不行,因为派生类的新成员无值可赋。
2. 可以将一个派生类的对象的地址赋给其基类的指针变量,但只能通过这个指针访问派生
Student GStudent
EGStudent Person
Student 新成员 GStudent 新成员
Person Employee 新成员
Person 成员
Person Person Employe
类中由基类继承来的成员,不能访问派生类中的新成员。
同样也不能反过来做。
3.派生类对象可以初始化基类的引用。
引用是别名,但这个别名只能包含派生类对象中的由基类继承来的成员。
8.2.6比较派生与模板各自的优点。
答:模板追求的是运行效率,而派生追求的是编程的效率。
通用性是模板库的设计出发点之一,这是由泛型算法和函数对象等手段达到的。
为了运行的效率,类模板是相互独立的,即独立设计,没有使用继承的思想。
对类模板的扩展是采用适配子(adapter)来完成的。
应该说派生类的目标之一也是代码的复用和程序的通用性,最典型的就是MFC,派生类的优点是可以由简到繁,逐步深入,程序编制过程中可以充分利用前面的工作,一步步完成一个复杂的任务。
8.2.7是否使用了虚函数就能实现运行时的多态性?怎样才能实现运行时的多态性?
答:不是。
实现动态多态性时,必须使用基类类型的指针变量或引用,使该指针指向该基类的不同派生类的对象,并通过该指针指向虚函数,才能实现动态的多态性。
8.2.8为什么析构函数总是要求说明为虚函数?
答:在基类中及其派生类中都动态分配内存空间时,必须把析构函数定义为虚函数,实现撤消对象时的多态性。
根据赋值兼容规则可以用基类的指针指向派生类对象,如果由该指针撤销派生类对象,则必须将析构函数说明为虚函数,实现多态性,自动调用派生类析构函数。
我们总是要求将类设计成通用的,无论其他程序员怎样调用都必须保证不出错,所以必须把析构函数定义为虚函数。
8.2.9什么是抽象类?含有纯虚函数的类是抽象类吗?
答:若定义一个类,它只能用作基类来派生出新的类,而不能用来定义对象,则称为抽象类。
含有纯虚函数的类是抽象类。
二.编程与综合练习题
8.3请用类的派生方式来组织下列动物实体与概念:动物,脊椎动物亚门,节肢动物门,
鱼纲,鸟纲,爬行纲,哺乳纲,昆虫纲,鲨鱼,青鱼,海马,鹦鹉,海鸥,喜鹊,蝙蝠,翼龙,蜻蜓,金龟,扬子鳄,袋鼠,金丝猴,虎,蜈蚣,蜘蛛,蝗虫,知了,螃蟹,虾。
解:动物派生出:脊椎动物亚门和节肢动物门。
脊椎动物亚门派生出:鱼纲,鸟纲,爬行纲,哺乳纲。
鱼纲派生出:鲨鱼,青鱼,海马。
鸟纲派生出:鹦鹉,海鸥,喜鹊。
爬行纲派生出:翼龙,金龟,扬子鳄。
哺乳纲派生出:蝙蝠,袋鼠,金丝猴,虎。
节肢动物门派生出:昆虫纲,蜈蚣(多足纲),蜘蛛(蜘形纲),螃蟹,虾(甲壳纲)。
昆虫纲派生出:蜻蜓,蝗虫,知了。
8.4定义商品类及其多层的派生类。
以商品类为基类。
第一层派生出服装类、家电类、车
辆类。
第二层派生出衬衣类、外衣类、帽子类、鞋子类;空调类、电视类、音响类;
自行车类、轿车类、摩托车类。
要求给出基本属性和派生过程中增加的属性。
8.5以点(point)类为基类,重新定义矩形类和圆类。
点为直角坐标点,矩形水平放置,
由左下方的顶点和长宽定义。
圆由圆心和半径定义。
派生类操作判断任一坐标点是在图形内,还是在图形的边缘上,还是在图形外。
缺省初始化图形退化为点。
要求包括拷贝构造函数。
编程测试类设计是否正确。
8.6几何形体的派生关系如下:
对平面形体有长和面积,对立体有表面积和体积,对几何图形基类,周长、面积和体积
应怎样计算(用什么函数)?对平面图形体积怎样计算(用什么函数)?对立体图形周长怎么计算(用什么函数)?要求实现运行时的多态性。
请编程,并测试。
8.7某公司雇员(employee)包括经理(manager),技术人员(technician)和销售员(salesman)。
开发部经理(developermanger),既是经理也是技术人员。
销售部经理(salesmanager),既是经理也是销售员。
以employ类为虚基类派生出manager,technician和salesman类;再进一步派生出developermanager和salesmanager类。
employee类的属性包括姓名、职工号、工资级别,月薪(实发基本工资加业绩工资)。
操作包括月薪计算函数(pay()),该函数要求输入请假天数,扣去应扣工资后,得出实发基本工资。
technician类派生的属性有每小时附加酬金和当月工作时数,及研究完成进度系数。
业绩工资为三者之积。
也包括同名的pay()函数,工资总额为基本工资加业绩工资。
salesman类派生的属性有当月销售额和酬金提取百分比,业绩工资为两者之积。
也包括同名的pay()函数,工资总额为基本工资加业绩工资。
manager类派生属性有固定奖金额和业绩系数,业绩工资为两者之积。
工资总额也为基本工资加业绩工资。
而developermanager类,pay()函数是将作为经理和作为技术人员业绩工资之和的一半作为业绩工资。
salesamanager类,pay()函数则是经理的固定奖金额的一半,加上部门总销售额与提成比例之积,这是业绩工资。
编程实现工资管理。
特别注意pay()的定义和调用方法:先用同名覆盖,再用运行时多态。
8.8为上题添加拷贝构造函数,并测试是否正确。