第09章习题解答
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
9.6习题
9.6.1 概念题
1.派生类成员由哪些部分组成?它们在派生类中起了些什么作用?
答:总起来说,除构造函数和析构函数以外,派生类的成员有原基类成员组和新增成员组两部分。这两部分成员起到了下面三方面的作用:
(1)原基类成员组体现了派生类继承了基类的全部特征和功能。
(2)新增成员组体现了派生类在功能上比基类有所发展。
(3)派生类在新增成员中,可设置与原基类成员同名的成员特别是同名的成员函数,其函数体可以有所不同。这体现了派生类可以对所继承的基类的特征和功能加以改进。
2.派生类中各成员存间怎么安排?
答:派生类对象声明以后,系统为派生类对象各数据成员配给相应存间。存间是连续安排的。总的来说,原基类数据成员们存间在前,新增数据成员们存间在后。若同时继承多个基类,有多个数据成员,则按派生类定义中基类顺序和数据成员顺序安排先后次序。至于成员函数,则仍按过去所说的,在内存的一个公用区安排存放,供该类的所有对象共享。
3.派生类中各成员身分怎样确定?访问派生类中各成员,要遵循什么规则进行?
答:派生类中的原基类成员们根据“身分确定规则”重新确定身分。而派生类本身新增成员们的身分在派生类定义时就已确定好。因此,派生类中所有成员都有了明确的身分。对派生类各成员进行访问时,就一概按“访问控制规则”办就行啦。
4.定义派生类时,如何对原基类数据成员进行初始化?
答:对派生类对象进行初始化时,要调用基类构造函数对原基类数据成员组进行初始化,派生类构造函数类外定义的一般形式为:
派生类名::派生类名(参数总表):基类名1(参数表1),…,基类名n (参数表n)
{ 派生类新增成员初始化语句;}
冒号后面的列表是调用各基类构造函数用的。列表相互间用逗号隔开。列表们的顺序可以任意,但各括弧内的参数应与各基类构造函数的参数相对应。
5.派生类中能否直接访问原基类私有成员?如何能实现访问原基类私有成员?
答:因为原基类私有成员被继承到派生类中成为不可访问的成员。所以派生类中不能直接访问原基类私有成员。但是可以通过原基类的公有成员或保护成员间接地访问原基类的私有成员。
6.在什么情况下会出现二义性?如何处理?
答:如果在派生类中基类成员和新增成员之间出现了同名数据成员和同名成员函数,则访问这些成员的语句的含义就不确定,这就叫做二义性。
可以用原所在的类的类名加域运算符::法来对同名成员进行区分。这是避免二义性的基本方法。但若要访问派生类新增同名成员,则根据同名覆盖原理,可通过派生类对象直接访问之,而不必用域运算符指示。
7.在什么情况下会出现一个数据多种版本?如何处理?
答:具有共同基类的多级多脉继承所产生的派生类中会出现一个数据多种版本的问题。可采取下列两项措施避免之:
(1)在定义共同基类的直接派生类时,在继承方式前都加一个关键字“virtual”。这样就把共同基类设置成为虚基类了。
(2)对虚基类而言,不仅所有直接派生类,而且所有间接派生类的基类初始化列表中都必须有对虚基类的初始化列表。若没有,则虚基类的构造函数中必须有默认值。否则在编译时会认为出错。
8.例9-2中,看表9-3末行,pvx是不可访问的,为何竟能在程序运行最后得到输出结果?
答:看表9-3,pvx成员原在基类中时,是“私有成员”身分。原基类成员函数showx 是可以访问它的。但pvx被继承到派生类中,其身分变成“不可访问”。想用派生类新增成员函数showy直接访问它就办不到了。但showx函数继承到派生类中的身分是“保护成员”,showy是可以访问 showx的。因此通过这个关系,showy可以访问showx,而showx可以访问pvx,这样就使showy间接访问到pvx了。例9-2就是这样做的。看看showy和showx的函数体就明白了。
9.如果例9-1中,Y类对X类的继承方式改为保护继承和私有继承,则表示派生类Y中各成员身分的表9-2将会发生变化,试分别列出这两种情况下,表9-2变化后的情况。
答:如果例9-1中,Y类对X类的继承方式改为保护继承,则表如下:
派生类Y的成员们及其身分的确定(最终见本表末行)
派生类Y的成员们及其身分的确定(最终见本表末行)
何能访问showx?
答:因为b1是派生类对象,而showx在派生类中是“保护成员”身分,在类外是不可访问的。所以不能通过派生类对象b1访问showx。
但是,在派生类内,保护成员showx是可以被访问的,例如,派生类成员函数showy 就可访问showx。体现在showy的函数体内,访问了showx。
11.试问下列程序运行后,会获得什么结果?如果在A行show前加virtual,又会获得什么结果?
#include
using namespace std;
class X{
public:
void show(){cout<<"X::show"< }; class Y:public X{ public: void show(){cout<<"Y::show"< }; class Z:public Y{ public: void show(){cout<<"Z::show"< }; void fun(X *p){ p->show(); } int main() { X x; Y y; Z z; fun(&x); fun(&y); fun(&z); return 0; } 答:在A行show前未加virtual时,运行结果为: X::show X::show X::show 若在A行show前加了virtual,则运行结果为: X::show Y::show Z::show 9.6.2程序设计题 1.试设计程序,定义一个有平面坐标作为数据成员的point类作为基类。派生出直线段line类,有计算线段长度的成员函数。主函数中声明一个line类对象,输出该线段的长度。 #include #include using namespace std; class point{ protected: double x1,y1; public: point(double a,double b){x1=a;y1=b;} }; class line:public point{ private: