第7章 继承
习题7
7.1 选择题
1.在c++中,类之间的继承关系具有( c )。
(a) 自反性 (b) 对称性 (c) 传递性 (d) 反对称性 2.下列关于类的继承描述中,( d )是正确的。
(a) 派生类公有继承基类时,可以访问基类的所有数据成员,调用所有成员函数 (b) 派生类也是基类,所以它们是等价的
(c) 派生类对象不会建立基类的私有数据成员,所以不能访问基类的私有数据成员 (d) 一个基类可以有多个派生类,一个派生类可以有多个基类
3.当一个派生类公有继承一个基类时,基类中的所有公有成员成为派生类的( a )。 (a) public成员 (b)private成员 (c) protected成员 (d)友员 4.当一个派生类私有继承一个基类时,基类中的所有公有成员和保护成员成为派生类的( b )。
(a) public成员 (b)private成员 (c) protected成员 (d)友员 5.当一个派生类保护继承一个基类时,基类中的所有公有成员和保护成员成为派生类的( c )。
(a) public成员 (b)private成员 (c) protected成员 (d)友员 6.不论派生类以何种方式继承基类,都不能直接使用基类的( b )。 (a) public 成员 (b)private成员 (c) protected成员 (d)public 成员和protected成员 7.下面描述中,错误的是( d )。
(a) 在基类定义的public成员在公有继承的派生类中可见,也能在类外被访问 (b) 在基类定义的protected成员在私有继承的派生类中可见 (c) 在基类定义的静态成员在私有继承的派生类中可见
(d) 访问声明可以在公有继承派生类中把基类的public成员声明为private成员 8.在c++中,可以被派生类继承的函数是( a )。
(a) 成员函数 (b)构造函数 (c) 析构函数 (d)友员函数 9.在创建派生类对象时,构造函数的执行顺序是( d )。
(a) 对象成员构造函数、基类构造函数、派生类本身的构造函数 (b) 派生类本身的构造函数、基类构造函数、对象成员构造函数 (c) 基类构造函数、派生类本身的构造函数、对象成员构造函数 (d) 基类构造函数、对象成员构造函数、派生类本身的构造函数 10.当不同的类具有相同的间接基类时,有特点( c )。 (a) 各派生类对无法按继承路线产生自己的基类版本
(b) 为了建立惟一的间接基类版本,应该声明间接基类为虚类 (c) 为了建立惟一的间接基类版本,应该声明派生类虚继承基类 (d) 一旦声明虚继承,基类的性质就改变了,不能再定义新的派生类 7.2 阅读下列程序,写出执行结果
1.#include
class Base { public:
void get( int i,int j,int k,int l ) { a = i; b = j; x = k; y = l; } void print()
{ cout << \
<< \
}
int a,b;
protected: int x, y; };
class A: public Base { public:
void get( int i, int j, int k, int l ) { Base obj3;
obj3.get( 50, 60, 70, 80 ); obj3.print();
a = i; b = j; x = k; y = l;
u = a + b + obj3.a ; v = y - x + obj3.b;
}
void print()
{ cout << \
<< \
cout << \
} private:
int u, v ; };
void main() { Base obj1; A obj2;
obj1.get( 10, 20, 30, 40 ); obj2.get( 30, 40, 50, 60 ); obj1.print(); obj2.print(); } 【答案】
a = 50 b = 60 x = 70 y = 80 a = 10 b = 20 x = 30 y = 40 a = 30 b = 40 x = 50 y = 60 u = 120 v = 70
2. #include
class Base1
{ public:
Base1( int i ) { cout << \调用基类Base1的构造函数:\};
class Base2 { public:
Base2( int j ) { cout << \调用基类Base2的构造函数:\};
class A: public Base1, public Base2 { public:
A( int a, int b, int c, int d ) : Base2(b), Base1(c), b2(a), b1(d) { cout << \调用派生类A的构造函数:\
private: Base1 b1; Base2 b2; } ;
void main()
{ A obj( 1, 2, 3, 4 ); } 【答案】
调用基类BASE1的构造函数:3 调用基类BASE2的构造函数:2 调用基类BASE1的构造函数:4 调用基类BASE2构造函数:1 调用派生类A的构造函数:10 3. #include
class A { public:
A(int i, int j) {a=i; b=j ;}
void Add(int x, int y) { a+=x; b+=y;}
void show() { cout<<\ private: int a, b; };
class B : public A { public:
B(int i, int j, int m, int n):A(i,j),x(m),y(n){} void show() { cout<<\void fun() { Add(3,5); } void ff() { A::show(); } private:
int x, y ; };
void main() { A a(1,2); a.show();
B b(3,4,5,6); b.fun(); b.A::show(); b.show(); b.ff(); } 【答案】
(1) (2) (6) (9) (5) (6) (6) (9) 4. #include
class A { public:
A(const char *s){cout<
class B : virtual public A { public:
B(const char *s1, const char *s2):A(s1)
{ cout << s2 << endl ; } };
class C : virtual public A { public:
C(const char *s1, const char *s2):A(s1)
{ cout << s2 << endl ; } };
class D : public B, public C { public:
D(const char *s1,const char *s2,const char *s3,const char *s4) : B(s1,s2),C(s1,s3),A(s1) { cout << s4 << endl ; } };
void main()
{ D *ptr = new D(\ delete ptr; } 【答案】
class A class B class C class D 7.3 思考题
1. 函数和类两种程序模块都可以实现软件重用,它们之间有什么区别?
2.请按照类成员的访问特性、类层次的继承特点,做出一张表格,总结各种类成员在基类、派生类中的可见性和作用域。
3. 若有以下说明语句: class A
{ private: int a1;
public: int a2; double x; /*?*/ };
class B : private A
{ private: int b1;
public int b2; double x; /*?*/ };
B b ;
对象b将会生成什么数据成员?与继承关系、访问特性、名字有关吗?
4.若有以下说明语句:
class A { /*?*/ public : void sameFun(); }; class B : public A
{ /*?*/ public : void sameFun(); }; void comFun() { A a ; B b ; /*?*/ }
(1) 若在B::sameFun中要调用A::sameFun,语句形式如何?它将在什么对象上操作? (2) 在comFun中可以用什么方式调用A::sameFun和B::sameFun?语句形式如何?它们将可以在什么对象上操作?
5.“虚基类”是通过什么方式定义的?如果类A有派生类B,C,D,类A是类B和类C的虚基类,那它也一定是类D的虚基类吗?为什么?
6.在具有虚继承的类体系中,建立派生类对象时以什么顺序调用构造函数?请用简单程序说明,并上机验证你的分析。
7.4 编程题
1.定义一个Rectangle类,它包含两个数据成员length和width;以及包含用于求长方形面积的成员函数。再定义Rectangle的派生类Rectangular,它包含一个新数据成员height和用来求长方体体积的成员函数。在main函数中,使用两个类,求某个长方形的面积和某个长方体的体积。
【解答】
#include
rectangle( float l,float w ) float area()
{ length = l;width = w; }