第4章:继承与派生类[4_1]答:类的继承方式有public(公有继承)、protected(保护继承)和private(私有继承)3种,不同的继承方式导致原来具有不同访问属性的基类成员在派生类中的访问属性也有所不同。(1)基类中的私有成员无论哪种继承方式,基类中的私有成员不允许派生类继承,即在派生类中是不可直接访问的。(2)基类中的公有成员当类的继承方式为公有继承时,基类中的所有公有成员在派生类中仍以公有成员的身份出现;当类的继承方式为私有继承时,基类中的所有公有成员在派生类中都以私有成员的身份出现;当类的继承方式为保护继承时,基类中的所有公有成员在派生类中都是以保护成员的身份出现。(3)基类中的保护成员当类的继承方式为公有继承时,基类中的所有保护成员在派生类中仍以保护成员的身份出现;当类的继承方式为私有继承时,基类中的所有保护成员在派生类中都是以私有成员的身份出现:当类的继承方式为保护继承时,基类中的所有保护成员在派生类中仍以保护成员的身份出现。[4_2]答:派生类不能直接访问基类的私有成员,但是可以通过基类提供的公有成员函数间接地访问基类的私有成员。[4_3]答:保护成员可以被派生类的成员函数访问,但是对于外界是隐藏起来的,外部函数不能访问它。因此,为了便于派生类的访问,可以将基类私有成员中需要提供给派生类访问的成员定义为保护成员。C++规定,派生类对于保护成员的继承与公有成员的继承很相似,也分为两种情况:若为公有派生,则基类中的保护成员在派生类中也为保护成员;若为私有派生,则基类中的保护成员在派生类中成为私有成员。[4_4]答:通常情况下,当创建派生类对象时,首先执行基类的构造函数,随后再执行派生类的构造函数;当撤消派生类对象时,则先执行派生类的析构函数,随后再执行基类的析构函数。[4_5]答:当基类的构造函数没有参数或没有显示定义构造函数时,派生类可以不向基类传递参数,甚至可以不定义构造函数。当基类含有带参数的构造函数时,派生类必须定义构造函数,以提供把参数传递给基类构造函数的途径。派生类构造函数的一般格式如下:派生类构造函数名(参数总表):基类构造函数名(参数表){派生类新增数据成员的初始化语句}其中基类构造函数的参数,通常来源于派生类构造函数的参数表,也可以用常数值。由于析构函数是不带参数的,在派生类中是否定义析构函数与它所属的基类无关,基类的析构函数不会因为派生类没有析构函数而得不到执行,它们各自是独立的。[4_6]答:当一个派生类具有多个基类时,这种派生方法称为多继承。多继承构造函数的执行顺序与单继承构造函数的执行顺序相同,也是遵循先执行基类的构造函数,再执行对象成员的构造函数,最后执行派生类构造函数的原则。在多个基类之间则严格按照派生类声明时从左到右的顺序来排列先后。而析构函数的执行顺序刚好与构造函数的执行顺序相反。[4_7]在类的派生中为何要引入虚基类?虚基类构造函数的调用顺序是如何规定的?答:当引用派生类的成员时,首先在派生类自身的作用域中寻找这个成员,如果没有找到,则到它的基类中寻找。如果一个派生类是从多个基类派生来的,而这些基类又有一个共同的基类,则在这个派生类中访问这个共同的基类中的成员时,可能会产生二义性。为了解决这种二义性,C++引入了虚基类的概念。虚基类构造函数的调用顺序是:(1)若同一层次中包含多个虚基类,这些虚基类的构造函数按它们的说明的先后次序调用。(2)若虚基类由非虚基类派生而来,则仍然先调用基类构造函数,再调用派生类的构造函数。(3)若同一层次中同时包含虚基类和非虚基类,应先调用虚基类的构造函数,再调用非虚基类的构造函数,最后调用派生类构造函数。[4_8]A[4_9]C[4_10]C[4_11]B[4_12]运行结果是:ConstructorB2.ConstructorB1.ConstructorA.321[4_13]运行结果是:主食=bread副食=steak[4_14]运行结果是:0,0,00,1,03,6,9[4_15]运行结果是:ConstructorB2.2ConstructorB1.1ConstructorB3.3ConstructorA.4124,3[4_16]运行结果是:4[4_17]运行结果是:(1,2)5,6(6,9)[4_18]运行结果是:classbase1classbase2classlevel2classbase2classlevel1classtoplevel[4_19]修改后的程序如下:#includeiostreamusingnamespacestd;#includeiomanipclasstable{protected:inti,j;public:table(intp,intq){i=p;j=q;}voidascii(void);};voidtable::ascii(void){intk=1;for(;ij;i++){coutsetw(4)i(char)i;if((k)%12==0)cout\n;k++;}cout\n;}classder_table:publictable{protected:char*c;public:der_table(intp,intq,char*m):table(p,q){c=m;}voidprint(void);};voidder_table::print(void){coutc\n;table::ascii();}intmain(){der_tableob('a','z',ASCIIvalue---char);ob.print();return0;}4.20#includeiostreamusingnamespacestd;classarea_c1{protected:doubleheight;doublewidth;public:area_c1(doubler,doubles){height=r;width=s;}virtualdoublearea()=0;};classrectangle:publicarea_c1{public:rectangle(doubler,doubles):area_c1(r,s){}doublearea(){returnheight*width;}};classisosceles:publicarea_c1{public:isosceles(doubler,doubles):area_c1(r,s){}doublearea(){return0.5*height*width;}};intmain(){area_c1*pa;rectangler(10.0,5.0);isoscelesi(4.0,6.0);pa=&r;coutrectanglearea:pa-area()endl;pa=&i;coutisoscelesarea:pa-area()endl;return0;}[4_21]程序编制如下:#includeiostream#includestringusingnamespacestd;classTime{public:Time(inth,intm,ints){hours=h;minutes=m;seconds=s;}voiddisplay(){couthours:minutes:secondsendl;}protected:inthours,minutes,seconds;};classDate{public:Date(intm,intd,inty){month=m;day=d;year=y;}voiddisplay(){coutmonth/day/year;}protected:intmonth,day,year;};classBirthtime:publicTime,publicDate{public:Birthtime(char*cn,intmm,intdd,intyy,inthh,intmint,intss):Time(hh,mint,ss),Date(mm,dd,yy){strcpy(childname,cn);}voiddisplay(){coutchildname'';Date::display();coutendl;Time::display();}protected:charchildname[20];};intmain(){Birthtimeyx(yuanxiang,10,27,1966,13,20,0);yx.display();return0;}[4_22]实现本题功能的程序如下:#includeiostreamusingnamespacestd;classperson{public:voidinput(){cout姓名:;cinname;cout编号:;cinno;}voiddisp(){cout编号:noendl;cout姓名:nameendl;}private:intno;charname[l0];};classstudent:publicperson{public:voidinput(){person::input();cout班号:;cindepart;cout成绩:;cindegree;}voiddisp(){person::disp();cout班号:departendl;cout成绩:degreeendl;}private:chardepart[10];intdegree;};classteacher:publicperson{public:voidinput(){person::input();cout职称:;cinprof;cout部门:;cindepart;}voiddisp(){person::disp();cout职称:profendl;cout部门:departendl;}private:charprof[10];chardepart[l0];};intmain(){students1;teachert1;cout输入一个学生数据:endl;s1.input();cout输入一个教师数据:endl;t1.input();cout显示一个学生数据:endl;s1.disp();cout显示一个教师数据:endl;t1.disp();return0;}