第九章继承与派生类9.2 典型例题分析与解答例题1:下列对派生类的描述中,()是错误的。
A.一个派生类可以作为另一个派生类的基类B.派生类至少有一个基类C.派生类的成员除了它自己的成员外,还包含了它的基类成员D.派生类中继承的基类成员的访问权限到派生类保持不变答案:D分析:一个派生类可以作为另一个派生类的基类。
无论是单继承还是多继承,派生类至少有成的成员时可能出现二义性。
消除二义性的方法是采用作用域运算符。
派生类和它的基类中出现同名函数时,不可能出现二义性。
例题4:多继承派生类构造函数构造对象时,()被最先调用。
A.派生类自己的构造函数 B.虚基类的构造函数C.非虚基类的构造函数D.派生类中子对象类的构造函数答案:B分析:多继承派生类构造函数构造对象时,构造函数的调顺序是:虚基类的构造函数,派生类中子对象类的构造函数,派生类自己的构造函数。
例题5:C++类体系中,能被派生类继承的是()。
A.构造函数B.虚函数C.析构函数D.友元函数答案:B分析:C++类体系中,构造函数、析构函数和友元函数是不能被派生类继承的.例题6:设有基类定义:class Cbase{ private: int a;protected: int b;public: int c;};用派生类中子对象类的析构函数,最后调用基类的析构函数。
例题11:设有以下类的定义:class A class B: protected A class C: private B{ int A1; { int b1; { int c1;protected: int A2; protected: int b2; protected: int c2;public: int A3; public: int b3; public: int c3;}; }; };请按访问权限写出派生类C中具有的成员。
私有成员: (1)保护成员: (2)公有成员: (3) 。
答案:(1)c1、b2、b3、A2、A3 (2)c2 (3)c3分析:B类有它自己的私有成员b1、保护成员b2和公有成员有b3,另外B类是以保护方式从A类中派生出来的,所以A类保护成员A2和公有成员A3在B类中都变成保护类型的;C类有自己的私有成员c1、保护成员c2和公有成员有c3,C类是以私有方式从B类中派生出来的,所以B类中的b2、b3、A2和A3在C类中都变成私有的访问方式。
例题12:指出并改正下面程序中的错误。
#include<iostream.h>class Point种:1)将Rectangle的继承方式改为公有继承public;2)在Rectangle类中重定义move(),getx()和gety()函数,覆盖基类的同名函数。
void Rectangle::move(int xoffset,int yoffset){Point::move(xoffset,yoffset);}void Rectangle::getx(){return Point::getx();}void Rectangle::gety(){return Point::gety();}例题13:指出并改正下面程序中的错误。
#include<iostream.h>class A{ public:A(int a=0) {x=a;}void display() { cout<<"A.x="<<x<<endl; }};class B{ public:int x;B(int a=0) {x=a;}void display() {cout<<"B.x="<<x<<endl; } };class C:public A,public Bvoid showi(){cout << i<< ",";}int Geti(){return i;}};class Derived:public Base{ int j;Base aa;public:Derived(int n,int m,int p):Base(m),aa(p){cout << "Constructing derived class" <<endl;j=n;~Derived(){cout <<"Destructing derived class"<<endl;}void show(){Base::showi();cout << j<<"," << aa.Geti() << endl;}};void main(){ Derived obj(8,13,24);obj.show();}说明:派生类的构造函数的执行次序,先调用基类的构造函数,再调用派生类中子对象类的构造函数,最后调用派生类的构造函数。
析构函数的执行次序与构造函数正好相反,先调用D.多样性答案:B(3)下列对基类和派生类关系的描述中,错误的是()。
A.派生类是基类的具体化B.派生类是基类的子集C.派生类是基类定义的延续D.派生类是基类的组合答案:B(4)下列对派生类的描述中,错误的是()。
A.一个派生类可以作为另一个派生类的基类B.派生类至少有一个基类C.派生类的缺省继承方式是privateD.派生类只含有基类的公有成员和保护成员答案:D(5)下列对继承的描述中,错误的是()。
A.析构函数不能被继承B.派生类也是基类的组合C.派生类的成员除了它自己的成员外,还包含了它的基类的成员D.派生类中继承的基类成员的访问权限到派生类保持不变A.简化程序B.消除二义性C.提高运行效率D.减少目标代码答案:B(11)下列虚基类的声明中,正确的是( D )。
A.class virtual B:public AB.virtual class B:public AC.class B:public A virtualD.class B: virtual public A答案:D(12)在下面的表达式中,不表示虚继承的是()。
A.virtual publicB.public virtualC.publicD. virtual答案:C2.比较类的三种继承方式public(公有继承)、protected(保护继承)、private(私有继承)之间的差别。
答:继承方式决定了基类中的成员在派生类中的属性。
三种继承方式的共同点:基类的private 成员在派生类中不可见。
区别:对于私有继承,基类的public,protected成员在派生类中作为private成员;对于公有继承,基类的public,protected成员在派生类中访问属性不变;对于保护继承,基类的public,protected成员在派生类中作为protected成员。
3. 派生类构造函数执行的次序是怎样的?答:派生类构造函数的执行顺序是先执行所有基类的构造函数(顺序按照定义派生类是指定B}};class Rectangle:public shape{ double x,y;public:Rectangle(double x1=0,double y1=0) {x=x1;y=y1;}void GetArea() {s=x*y;}};class Circle:public shape{ double r;public:Circle(double r1=0) {r=r1;}void GetArea() {s=r*r*PI; }};class Square :public Rectangle{ double a;public:Square(double a1=0 ) {a=a1;}void GetArea() {s=a*a; }};char zy[10]; //专业double score; //入学成绩…………};9.4补充习题1.选择题(2)设有如下程序:#include<iostream.h>class A{ public: int i;display() { cout<<”class A\n”; }};class B{public: int i;display() { cout<<”class B\n”; }};class C: public: A,public B{ int j;public:int i;show()2.填空题(1) 生成一个派生类对象时,先调用 (1) 的构造函数,然后调用 (2) 的构造函数。
(2) 继承发生在利用现有类派生新类时,其中 (1) 称为基类,或 (2) 类; (3) 称为派生类,或 (4) 类。
(3) 在继承关系中, (1) 称为多重继承, (2) 称为多层继承。
(4) 在公有继承关系下,派生类的对象可以访问基类中的 (1) 成员,派生类的成员函数可以访问基类中的 (2) 成员。
(5) 在保护继承关系下,基类的公有成员和保护成员将成为派生类中的 (1) 成员,它们只能由派生类的 (2) 来访问;基类的私有成员将成为派生类中的 (3) 成员。
4.编程题(2)定义一个车基类Vehicle,含私有成员speed,weight。
派生出自行车类Bicycle,增加high成员;汽车类Car,增加seatnum成员。
从bicycle和car中派生出摩托车类Motocycle。