第四章——派生类和继承作业
一、单选题(共20题,100分)
1.有如下类定义:
class Father{ //基类
public:
Father(string s):name(s) { }
private:
string name;
};
class Mother{ //基类
public:
Mother(string s):name(s) { }
private:
string name;
};
【1】 //Father和Mother的派生类
public:
Child(string s1,string s2,string s3):Father(s1),Mother(s2),name(s3) { }
private:
string name;
};
若派生类Child从基类Father和基类Mother处公有继承,则程序中【1】处缺失的部分是( )。
A.class Child
B.class Child:Father,Mother
C.class Child:public Father,Mother
D.class Child:public Father,public Mother
我的答案: D正确答案: D
答案解析:一个派生类同时继承两个或者多个基类时称为多重继承,其一般形式为:
class 派生类名:[继承方式]基类名1,[继承方式]基类名2,所以D选项正确。
2.
有如下程序:
#include<iostream>
#include<string>
using namespace std;
class Wheel{
public:
Wheel(string s="W"):name(s) { cout<<name; }
~Wheel() { cout<<name; }
private:
string name;
};
class Bicycle{
public:
Bicycle(string br="G",string f="F",string r="R"):brand(br),rear(r),front(f) { cout<<brand; }
~Bicycle() { cout<<brand; }
private:
Wheel front,rear;
string brand;
};
int main(){
Bicycle bike;
return 0;
}
运行时的输出结果是( )。
A.RFG
B.FRG
C.FRGGRF
D.FRGFRG
我的答案: C正确答案: C
答案解析:定义Bicycle bike时,执行Wheel的构造函数输出FR,然后执行Bicycle的构造函数输出G,最后执行析构函数,一次执行派生类的析构函数输出G,再输出基类的析构函数输出RF,最终输出FRGGRF,选项C正确。
3.有如下程序:
#include <iostream>
using namespace std;
class Point{
int x,y;
public:
Point(int x1=0, int y1=0):x(x1),y(y1) {}
int get() {return x+y;}
};
class Circle{
Point center;
int radius;
public:
Circle(int cx, int cy, int r):center(cx,cy),radius(r) {}
int get() {return center.get()+radius;}
};
int main() {
Circle c(3,4,5);
cout<<c.get()<<endl;
return 0;
}
运行时的输出结果是( )。
A.5
B.7
C.12
D. 9
我的答案: C正确答案: C
答案解析:
本题考查构造函数,题目中定义了Circle类,在类体中又定义了Point的对象,执行Circle c(3,4,5);后输出三个数之和,所以是12,C选项正确。
4. (单选题)
有如下类定义:
class Cup{
public:
void SetPrice(double val=5.8);
double GetPrice() { return price; }
double GetPrice() const { return price; }
private:
double price;
};
void Cup::SetPrice(double val) { price=val; }
下列关于类中成员函数的叙述中,错误的是( )。
A.成员函数SetPrice不是内联函数
B.成员函数SetPrice的形参val具有默认值
C.成员函数GetPrice可以重载
D.类中没有对成员函数GetPrice进行重载
我的答案: D正确答案: D
答案解析:在类体中定义的成员函数,C++系统会自动将它们作为内联函数处理,而在类外定义的成员函数,系统并不把它们默认为内联函数,所以SetPrice不是内联函数,SetPrice的形参val具有默认值5.8,类体中有两个GetPrice,所以这是对GetPrice 函数进行了重载,D选项错误。
5.下列有关类继承的表述中,错误的是( )。
A.继承可以实现软件复用
B.派生类构造函数要负责调用基类的构造函数
C.虚基类可以解决由多继承产生的二义性问题
D.派生类没有继承基类的私有成员
我的答案: D正确答案: D
答案解析:软件方面的可重用性是通过继承来实现的,A选项正确。派生类的构造函数负责调用基类的构造函数,B选项正确。虚基类解决了由多继承产生的二义性问题,所以C选项正确。派生类可以继承基类的私有成员,但是不能直接访问,所以D选项错误。
6.有如下程序:
#include<iostream>
#include<string>
using namespace std;
class Appliance{
public:
Appliance(string t="A"):type(t) { }
~Appliance() { cout<<type; }
public:
string type;
};
class TV:public Appliance{
public:
TV():size(0) { }
TV(int s):Appliance("T"), size(s) { }
~TV() { cout<<size; }
private:
int size;
};
int main(){
TV room1,room2(41);
return 0;
运行时的输出结果是( )。
A.041
B.410
C.0A41T
D.41T0A
我的答案: D正确答案: D
答案解析:执行派生类构造函数的顺序是:
1、调用基类构造函数,2、调用子对象构造函数,3、再执行派生类析构函数,4、执行基类的析构函数,所以本题中定义分别定义了room1,room2后,调用构造函数后没有输出,而调用析构函数的顺序依次为room2的析构函数,输出41,然后执行Appliance的析构函数输出T,然后执行room1的析构函数输出0,最后执行Appliance的析构函数输出A,所以D选项正确。
7.下列有关继承和派生的表述中,正确的是( )。
A.作为虚基类的类不能被实例化
B.派生类不能访问基类的保护成员
C.派生类应当向基类的构造函数传递参数
D.虚函数必须在派生类中重新实现
我的答案: C正确答案: C
答案解析:
作为虚基类的类可以被实例化,派生类公用继承和保护继承基类,都可以访问基类的保护成员。如果派生类没有对虚函数重新定义,那么就调用基类的虚函数。所以C选项正确。
8.有如下程序:
#include<iostream>
using namespace std;
class Appliance{
public:
Appliance() { }
~Appliance() { cout<<'A'; }
};
class TV:public Appliance{
public:
TV(int s=41):size(s) { }
~TV() { cout<<'T'<<size; }
private:
int size;
};
int main(){
TV room1,*room2;
return 0;
}
A.T41
B.T41A
C.T41T41
D.T41AT41A
我的答案: B正确答案: B
答案解析:执行派生类构造函数的顺序是:
1、调用基类构造函数,2、调用子对象构造函数,3、再执行派生类析构函数,4、执行基类的析构函数,所以本题中定义room1时,程序结束时先调用派生类析构函数输出T41,然后执行基类的析构函数输出A,而定义对象指针,并不会调用构造函数,所以什么也不输出,所以结果为T41A,B选项正确。
9. (单选题)
有如下程序:
#include<iostream>
using namespace std;
class Appliance{
public:
Appliance() { cout<<'A'; }
~Appliance() { }
};
class TV:public Appliance{
public:
TV(int s=41):size(s) { cout<<'T'<<size; }
~TV() { }
private:
int size;
};
int main(){
TV room1,*room2;
return 0;
}
运行时的输出结果是( )。
A.T41
B.AT41
C.T41T41
D. AT41AT41
我的答案: B正确答案: B
答案解析:执行派生类构造函数的顺序是:
1、调用基类构造函数,2、调用子对象构造函数,3、再执行派生类析构函数,4、执行基类的析构函数,所以本题中定义room1时,先调用基类构造函数输出A,然后执行TV的构造函数输出T41,而定义对象指针,并不会调用构造函数,所以什么也不输出,结果为AT41,B 选项正确。
10. (单选题)
有如下程序:
#include<iostream>
#include<string>
using namespace std;
class Appliance{
public:
Appliance(string t="A"):type(t) { cout<<type; }
~Appliance() { }
public:
string type;
};
class TV:public Appliance{
public:
TV():size(0) { cout<<size; }
TV(int s):Appliance("T"), size(s) { cout<<size; }
~TV() { }
private:
int size;
};
int main(){
TV room1,room2(41);
return 0;
}
运行时的输出结果是( )。
A.041
B.0T41
C.A0A41
D. A0T41
我的答案: D正确答案: D
答案解析:执行派生类构造函数的顺序是:
1、调用基类构造函数,2、调用子对象构造函数,3、再执行派生类构造函数,所以本题中定义room1时,先调用基类构造函数输出A,然后执行TV的构造函数输出0,定义room2时,调用TV的构造函数,输出T41,所以结果为A0T41,答案为D选项。
11.#include<iostream>
#include<string>
using namespace std;
class Person{
public:
Person(string n):name(n) { cout<<'P'; }
private:
string name;
};
class Date{
public:
Date(int y=2012,int m=12,int d=21):year(y),month(m),day(d) { cout<<'D'; }
private:
int year,month,day;
};
class Student:public Person{
public:
Student(string n,int y,int m,int d,char c):birthday(y,m,d),sex(c),Person(n) { cout<<'S'; }
private:
Date birthday;
char sex;
};
int main(){
Student stu1("Zhang",1990,10,1,'F');
return 0;
}
运行时的输出结果是( )。
A.S
B.PS
C.DPS
D.PDS
我的答案: D正确答案: D
答案解析:本题考查派生类的构造函数,派生类的构造函数初始化时按照参数列表初始化顺序,所以先初始化Person(n),输出P,然后依次输出D和S,答案为D选项。
12. (单选题)
有如下类定义:
class Person{
public:
Person(string s):name(s) { }
protected:
string name;
};
class Father:virtual public Person{
public:
Father(string s):Person(s) { }
};
class Mother:virtual public Person{
public:
Mother(string s):Person(s) { }
};
class Child:public Father,public Mother,virtual public Person{
public:
Child(string s1,string s2,string s3):Mother(s1),Father(s2),Person(s3) { }
};
在建立派生类Child的对象时,其基类Father、Mother和Person的构造函数的调用顺序为( )。
A.Father,Mother,Person
B.Mother,Father,Person
C.Person,Father,Mother
D. Father,Person,Mother,Person,Person
我的答案: C正确答案: C
答案解析:执行派生类构造函数的顺序是:
1、调用基类构造函数,2、调用子对象构造函数,3、再执行派生类构造函数,所以本题中先调用基类person构造函数,然后执行father构造函数,最后执行mother构造函数。
13. (单选题)
有如下程序:
#include <iostream>
using namespace std;
class Base {
public:
void fun() { cout<<"Base::fun"<<endl; }
};
class Derived : public Base {
public:
void fun() {
【1】
cout<<"Derived::fun"<<endl;
}
};
int main() {
Derived d;
d.fun();
return 0;
}
已知其执行后的输出结果为:
Base::fun
Derived::fun
则程序中【1】处应填入的语句是( )。
A.Base.fun();
B.Base::fun();
C.Base->fun();
D. fun();
我的答案: B正确答案: B
答案解析:本题考查公用继承对基类成员的访问属性。在公用继承中,基类的公用成员和保护成员在派生类中保持原有的访问属性,其私有成员仍为基类私有。本题中想要输出Base::fun,则必须调用基类的公用成员函数fun,所以使用Base::fun();来调用基类的成员函数fun。
14.下列有关继承和派生的叙述中,正确的是( )。
A.如果一个派生类公有继承其基类,则该派生类对象可以访问基类的保护成员
B.派生类的成员函数可以访问基类的所有成员
C.基类对象可以赋值给派生类对象
D.如果派生类没有实现基类的一个纯虚函数,则该派生类是一个抽象类
我的答案: D正确答案: D
答案解析:私有继承方式为基类的公用成员和保护成员在派生类中成了私有成员,其私有成员仍为基类私有,但派生类对象可以访问基类的保护成员,所以基类对象不能赋值给派生类对象。抽象类是指含有纯虚拟函数的类,所以选项D正确。
15. (单选题)下列关于继承和派生的叙述中,正确的是( )。
A.派生类中新定义的成员函数可以访问基类的所有成员
B.在私有继承的情况下,派生类中新定义的成员函数不能访问基类的保护成员
C.基类对象可以赋值给派生类对象
D.如果派生类没有实现基类的一个纯虚函数,则该派生类是一个抽象类
我的答案: D正确答案: D
答案解析:本题考查继承与派生,派生类中的成员访问基类中的成员由派生方式决定,如果派生类私有继承基类,那么就不能新定义的成员函数就不能访问基类的私有成员,所以A选项错误。在私有继承的情况下,派生类中新定义的成员函数可以访问基类的保护成员。基类对象在某种情况下可以赋值给派生类对象。
16.有如下程序:
#include<iostream>
using namespace std;
class Base {
int x;
public:
Base(int n=0): x(n) { cout<<n; }
int getX()const { return x; }
};
class Derived: public Base {
int y;
public:
Derived(int m, int n): y(m), Base(n) { cout<<m; }
Derived(int m): y(m) { cout<<m; }
};
int main()
{
Derived d1(3), d2(5,7);
return 0;
}
执行这个程序的输出结果是( )。
A.375
B.357
C.0375
D. 0357
我的答案: C正确答案: C
答案解析:本题考查派生类的构造函数和析构函数,在定义一个派生类的对象时,先调用基类的构造函数,然后再执行派生类的构造函数,派生类对象释放时,先执行派生类的析构函数,再执行基类的析构函数。本题中定义了一个对象d1,先执行基类的构造函数输出0,再执行派生类的构造函数输出3,然后定义了一个对象d2(5,7),其中需要调用基类的构造函数输出7,最后输出5,所以答案为C。
17.有如下程序:
#include <iostream>
using namespace std;
class A {
public:
A(int i) { x = i; }
void dispa () { cout << x <<′,′; }
private :
int x ;
};
class B : public A {
public:
B(int i) : A(i+10) { x = i; }
void dispb() { dispa(); cout << x << endl; }
private :
int x ;
};
int main() {
B b(2);
b.dispb();
return 0;
}
执行这个程序的输出结果是( )。
A.10,2
B.12,10
C.12,2
D.2,2
我的答案: C正确答案: C
答案解析:本题考查派生类的构造函数和基类的构造函数。本题中类B继承类A,定义了一个类B的对象并初始化b(2),此时会执行类B的构造函数,执行的结果是继承类A中的私有成员赋值了12,给类B自身的数据成员x赋值了2,执行b.dispb()后,输出类A的私有成员x,输出类B自身的数据成员,所以答案为C。
18.有如下程序:
#include <iostream>
using namespace std;
class Base {
protected:
Base() { cout<<′A′; }
Base(char c) { cout<<c; }
};
class Derived: public Base {
public:
Derived( char c ) { cout<<c; }
};
int main() {
Derived d1(′B′);
return 0;
}
执行这个程序的输出结果是( )。
A.B
B.BA
C.AB
D. BB
我的答案: C正确答案: C
答案解析:本题考查派生类的构造函数和析构函数,在定义一个派生类的对象时,先调用基类的构造函数,然后再执行派生类的构造函数;派生类对象释放时,先执行派生类的析构函数,再执行基类的析构函数。本题中定义了一个派生类对象d1,首先执行基类的构造函数,输出A;然后执行派生类的构造函数,输出B。所以答案为C。
19.有如下程序:
#include <iostream>
using namespace std;
class Base {
public:
Base(int x=0) { cout<<x; }
};
class Derived : public Base {
public:
Derived(int x=0) { cout<<x; }
private:
Base val;
};
int main()
{
Derived d(1);
return 0;
}
执行这个程序的输出结果是( )。
A.0
B.1
C.01
D.001
我的答案: D正确答案: D
答案解析:本题考查派生类的构造函数和析构函数,在定义一个派生类的对象时,先调用基类的构造函数,然后再执行派生类的构造函数,派生类对象释放时,先执行派生类的析构函数,再执行基类的析构函数。所以本题中定义了一个对象d,先执行基类的构造函数输出0,因为派生类中的私有数据成员为Base,所以还会执行一次基类的构造函数输出0,最后执行派生类的构造函数输出1,所以本题答案为D。
20.有如下程序:
#include <iostream>
using namespace std;
class A
{
public:
A() { cout<<"A"; }
~A() { cout<<"~A"; }
};
class B : public A
{
A* p;
public:
B() { cout<<"B"; p = new A(); }
~B() { cout<<"~B"; delete p; }
};
int main()
{
B obj;
return 0;
}
执行这个程序的输出结果是( )。
A.BAA~A~B~A
B.ABA~B~A~A
C.BAA~B~A~A
D.ABA ~A~B~A
我的答案: B正确答案: B
答案解析:本题考查派生类的构造函数和析构函数,在定义一个派生类的对象时,先调用基类的构造函数,然后再执行派生类的构造函数。派生类对象释放时,先执行派生类的析构函数,再执行基类的析构函数。所以本题答案为B。
所有习题完整版PDFhttps://download.csdn.net/download/lornaleo/75413292