第5章多态性
一、单选题(共17题,100分)
1下列有关继承和派生的叙述中,正确的是( )
A. 派生类不能访问基类的保护成员
B. 作为虚基类的类不能被实例化
C.派生类应当向基类的构造函数传递参数
D.虚函数必须在派生类中重新实现
我的答案: C正确答案: C
答案解析:答案解析 解析派生类可以访问基类的保护成员,而不能访问基类的私有成员。作为虚基类的类可以被实例化。虚函数如果没有派生类中重新实现,那么仍然使用基类的成员函数
2有如下类定义: class Shape{ public: 【1】 //纯虚函数Draw的声明 }; 程序中【1】处缺失的纯虚函数Draw的声明是( )。
A.void Draw()=0;
B.virtual void Draw()=0;
C.virtual void Draw(){ }
D. virtual void Draw(int=0);
我的答案: B正确答案: B
答案解析:在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去做。这就是纯虚函数的作用。一般形式如下:
class <类名>
{
virtual <类型> <函数名>(<参数表>)=0;
…
};
所以B选项正确。
3有如下程序:
#include <iostream>
using namespace std;
class Book {
public:
Book(char* t=" ") { strcpy(title,t); }
【1】
private:
char title[40];
};
class Novel : public Book {
public:
Novel(char* t=" "): Book(t) { }
char* Category()const { return "文学"; }
};
int main() {
Book *pb;
pb=new Novel();
cout<<pb->Category();
delete pb;
return 0;
}
若程序运行时输出结果是"文学",则程序中【1】处缺失的语句是( )。
A.char* Category();
B.char* Category()const;
C.virtual char* Category()const;
D. virtual char* Category()const=0;
我的答案: D正确答案: D
答案解析:本题考查纯虚函数和抽象类,纯虚函数是在声明虚函数时被"初始化"为0的函数,包含纯虚函数的类为抽象类,抽象类是不能被实例化的,但是可以定义指向抽象类数据的指针变量,当派生类成为具体类后,就可以用这种指针指向派生类的对象,然后通过该指针调用虚函数,实现多态性的操作。所以本题答案为D。
4.有如下程序:
#include<iostream>
using namespace std;
class GA {
public:
virtual int f() { return 1; }
};
class GB: public GA {
public:
virtual int f() { return 2; }
};
void show(GA g) { cout<<g.f(); }
void display(GA &g) { cout<<g.f(); }
int main()
{
GA a; show(a); display(a);
GB b; show(b); display(b);
return 0;
}
执行这个程序的输出结果是( )。
A.1111
B.1211
C.1112
D.1212
我的答案: C正确答案: C
5.8分
答案解析:本题主要考查虚函数。虚函数指在某基类中声明为virtual并在一个或多个派生类中被重新定义的成员函数,本题中定义类GA的对象a,执行show(a)、display(a),输出11,定义了类GB的对象b,执行show(b),仍然输出1,display(b)执行会调用派生类的f函数,因为f函数为虚函数,输出2,所以本题答案为C。
5有如下程序:
#include<iostream>
#include<string>
using namespace std;
class Instrument{
public:
Instrument(string t="乐器",string n="无名"):type(t),name(n) { }
virtual string GetType() const { return "乐器"; }
virtual string GetName() const { return "无名"; }
protected:
string type,name;
};
class Piano:public Instrument{
public:
Piano(string n,string t="钢琴"):Instrument(t,n) { }
string GetType() const { return "钢琴"; }
string GetName() const { return name; }
};
int main(){
Instrument *pi=new Piano("星空");
cout<<pi->GetType()<<'-'<<pi->GetName();
delete pi;
return 0;
}
运行时的输出结果是( )。
A.钢琴-星空
B. 钢琴-无名
C.乐器-星空
D.乐器-无名
我的答案: A正确答案: A
5.8分
答案解析:本题考查虚函数的运用,本题中基类Instrument,派生类Piano,其中虚函数为GetType,当定义Instrument *pi=new Piano("星空")时,调用派生类的GetType函数,得到type为钢琴,name为星空,所以输出钢琴-星空。选项A正确。
6有如下程序:
#include <iostream>
using namespace std;
int i=1;
class Fun {
public:
static int i;
int value(){ return i-1;}
int value()const{ return i+1;}
};
int Fun::i=2;
int main(){
int i=3;
Fun fun1;
const Fun fun2;
【1】
return 0;
}
若程序的输出结果是:
123
则程序中【1】处遗漏的语句是( )。
A. cout<<fun1.value()<<Fun::i<<fun2.value();
B. cout<<Fun::i<<fun1.value()<<fun2.value();
C. cout<<fun1.value()<<fun2.value()<<Fun::i;
D. cout<<fun2.value()<<Fun::i<<fun1.value();
我的答案: A正确答案: A
答案解析:本题考查构造函数、常成员函数和静态数据成员。外部同名的变量赋值,不能改变类的静态变量值,所以Fun对象里的i值为2,所以本题答案为A。
7有如下头文件:
int f1();
static int f2();
class MA {
public:
int f3();
static int f4();
};
在所描述的函数中,具有隐含的this指针的是( )。
A.f1
B.f2
C.f3
D. f4
我的答案: C正确答案: C
答案解析:只有类的非静态成员函数才隐含this指针,其作用域是类内部,当类的非静态成员函数中访问类的非静态成员时,编译器会自动将对象本身的地址作为一个隐含参数传递给函数,而不必一定写上this。所以本题答案为C。
8有如下程序:
#include <iostream>
using namespace std;
class MyClass {
public:
MyClass() { ++count; }
~MyClass() { --count; }
static int getCount() { return count; }
private:
static int count;
};
int MyClass::count=0;
int main()
{
MyClass obj;
cout<<obj.getCount();
MyClass *ptr=new MyClass;
cout<<MyClass::getCount();
delete ptr;
cout<<MyClass::getCount();
return 0;
}
执行这个程序的输出结果是( )。
A.121
B.232
C.221
D.122
我的答案: A正确答案: A
答案解析:本题考查静态数据成员。静态数据成员在内存中只占一份空间,静态数据成员属于类,即使不定义对象,也会给静态数据成员分配空间,可以被引用。本题中先是定义了一个对象obj,执行构造函数使得静态数据成员count变为了1,然后又定义了指针对象,执行构造函数后,count变为了2,释放指针后,执行析构函数,使得count变为了1。所以本题答案为A。
9有如下类定义:
class Test
{
public:
Test() { a = 0; c = 0; } // ①
int f(int a) const { this->a = a; } // ②
static int g() { return a; } // ③
void h(int b) { Test::b = b; }; // ④
private:
int a;
static int b;
const int c;
};
int Test::b = 0;
在标注号码的行中,能被正确编译的是( )。
A.①
B.②
C.③
D.④
我的答案: D正确答案: D
答案解析:只能通过构造函数的参数初始化列表对常数据成员进行初始化,本题中常数据成员为c。①通过默认构造函数初始化c,所以不正确。常成员函数只能引用本类中数据成员,而不能修改它,所以②不正确。静态成员函数由于没有this指针,所以不能访问本类中的非静态成员,所以③错误。
10有如下程序:
#include<iostream>
#include<string>
using namespace std;
class Animal{
public:
virtual string GetType() const { return "Animal"; }
virtual string GetVoice() const { return "Voice"; }
};
class Dog:public Animal{
public:
string GetType() const { return "Dog"; }
string GetVoice() const { return "Woof"; }
};
class Cat:public Animal{
public:
string GetType() const { return "Cat"; }
string GetVoice() const { return "Miaow"; }
};
void Type(Animal& a) { cout<<a.GetType(); }
void Speak(Animal a) { cout<<a.GetVoice(); }
int main() {
Dog d; Type(d); cout<<" speak "; Speak(d); cout<<" - ";
Cat c; Type(c); cout<<" speak "; Speak(c); cout<<endl;
return 0;
}
运行时的输出结果是( )。
A.Dog speak Voice - Cat speak Voice
B.Dog speak Woof - Cat speak Miaow
C.Animal speak Voice - Animal speak Voice
D. Animal speak Woof - Animal speak Miaow
我的答案: A正确答案: A
答案解析:本题考查虚函数的运用,本题中定义Dog d; Type(d)时,执行类Dog的GetType函数,输出Dog,然后输出speak,然后执行基类的Speak函数输出Voice,最后输出-,同理cat输出类似,所以结果为A选项正确。
11有如下程序:
#include <iostream>
using namespace std;
class B {
public:
virtual void show() { cout<<"B"; }
};
class D: public B {
public:
void show() { cout<<"D"; }
};
void fun1(B *ptr) { ptr->show(); }
void fun2(B &ref) { ref.show(); }
void fun3(B b) { b.show(); }
int main()
{
B b,*p=new D;
D d;
fun1(p);
fun2(b);
fun3(d);
delete p;
return 0;
}
执行这个程序的输出结果是( )。
A.BBB
B.BBD
C.DBB
D.DBD
我的答案: C正确答案: C
答案解析:本题考查虚函数。虚函数指在基类中声明为virtual并在一个或多个派生类中被重新定义的成员函数。本题中定义类B的对象 b、对象指针*p=new D以及类D的对象d;执行fun1会调用派生类的show函数,因为show函数为虚函数,而调用fun2、fun3仍然为基类的show函数,所以本题答案为C。
12有如下程序:
#include <iostream>
using namespace std;
class A {
public:
virtual void func1() { cout<<"A1"; }
void func2() { cout<<"A2"; }
};
class B:public A {
public:
void func1() { cout<<"B1"; }
void func2() { cout<<"B2"; }
};
int main() {
A *p=new B;
p->func1();
p->func2();
delete p;
return 0;
}
执行这个程序的输出结果是( )。
A.B1B2
B.A1A2
C.B1A2
D.A1B2
我的答案: C正确答案: C
答案解析:本题考查虚函数。虚函数指在基类中声明为virtual并在一个或多个派生类中被重新定义的成员函数。题中定义了一个派生类对象B,并使用类A的对象指针指向B,由于基类A中的func1为虚函数,所以会执行派生类的func1,输出B1,而基类中的func2不是虚函数,所以p->func2( )会执行基类的func2,输出A2。故答案为C。
13
有如下程序:
#include <iostream>
using namespace std;
class Instrument {
public:
virtual void Display()=0;
};
class Piano : public Instrument {
public:
void Display() { /*函数体略*/ }
};
int main() {
Instrument s;
Instrument *p=0;
//… ;
return 0;
}
下列叙述中正确的是( )。
A.语句"Insturment *p=0;"编译时出错
B.语句"Instrument s;"编译时出错
C.类Piano中的Display函数不是虚函数
D. 类Instrument是一个虚基类
我的答案: B正确答案: B
答案解析:本题考查纯虚函数和抽象类,纯虚函数是在声明虚函数时被"初始化"为0的函数,包含纯虚函数的类为抽象类,抽象类不能被实例化,所以语句"Instrument s;"在编译时出错。
14有如下程序:
#include <iostream>
using namespace std;
class Base
{
public:
void fun1() { cout<<"Base\n"; }
virtual void fun2() { cout<<"Base\n"; }
};
class Derived : public Base {
public:
void fun1() { cout<<"Derived\n"; }
void fun2() { cout<<"Derived\n"; }
};
void f(Base& b) { b.fun1(); b.fun2(); }
int main()
{
Derived obj;
f(obj);
return 0;
}
执行这个程序的输出结果是( )。
A. Base Base
B.Base Derived
C. Derived Base
D.Derived Derived
我的答案: B正确答案: B
答案解析:本题考查虚函数。虚函数指在基类中声明为virtual并在一个或多个派生类中被重新定义的成员函数。本题中定义了一个派生类对象obj,执行f函数后,将派生类对象obj转化为基类对象,由于fun1不是虚函数,所以调用基类的fun1;而fun2是虚函数,所以调用派生类的fun2,所以本题答案为B。
15有如下程序:
#include <iostream>
using namespace std;
class Base {
public:
void output() { cout<<1; }
virtual void Print() { cout<<′B′; }
};
class Derived : public Base {
public:
void output() { cout<<2; }
void Print() { cout<<′D′; }
};
int main()
{
Base *ptr=new Derived;
ptr->output();
ptr->Print();
delete ptr;
return 0;
}
执行这个程序的输出结果是( )。
A. 1B
B.1D
C.2B
D.2D
我的答案: B正确答案: B
答案解析:本题考查虚函数。虚函数指在基类中声明为virtual并在一个或多个派生类中被重新定义的成员函数。本题中定义了一个指向派生类对象的基类指针ptr,执行ptr->output后,会执行基类的output函数,输出1,由于Print是虚函数,所以ptr->Print()会执行派生类的Print,即输出D,所以本题答案为B。
16下列选项中,与实现运行时多态性无关的是( )。
A.重载函数
B.虚函数
C.引用
D.指针
我的答案: A正确答案: A
答案解析:运行时多态与虚函数有关。派生类的对象可以认为是基类的对象,但基类的对象不是其派生类的对象。因此,C++允许一个基类对象的指针指向其派生类对象,但不允许一个派生类对象指向其基类对象。在调用虚函数的过程中指针和引用会起到一定的作用。
17下列关于虚函数的叙述中,正确的是( )。
A.虚函数不得是静态成员函数
B.从虚基类继承的函数都是虚函数
C.只能通过指针或引用调用虚函数
D.抽象类中的成员函数都是虚函数
我的答案: A正确答案: A
答案解析:本题考查虚函数,在某基类中声明为 virtual 并在一个或多个派生类中被重新定义的成员函数成为虚函数,虚函数不得是静态成员函数,但可以是友元函数
所有习题完整版PDFhttps://download.csdn.net/download/lornaleo/75413292