c++多态性相关习题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
多态性
10.2 典型例题分析与解答
例题1:指出下列对定义重载函数的要求中,哪些是错误的提法。
A.要求参数的个数不同。
B.要求参数中至少有一个类型不同。
C.求函数的返回值不同。
D. 要求参数的个数相同时,参数类型不同。
答案: C
例题3:下面关于友元的描述中,错误的是()。
A. 友元函数可以访问该类的私有数据成员
B. 一个类的友元类中的成员函数都是这个类的友元函数
C. 友元可以提高程序的运行效率
D. 类与类之间的友元关系可以继承
答案:D
1
例题4:下述静态成员的特性中,()是错误的。
A. 静态成员函数不能利用this指针
B. 静态数据成员要在类体外进行初始化
C. 引用静态数据成员时,要在静态数据成员名前加<类名>和作用域运算符
D. 静态数据成员不是所有对象所共有的
答案:D
例题5:关于虚函数的描述中,()是正确的。
A. 虚函数是一个静态成员函数
B. 虚函数是一个非成员函数
C. 虚函数既可以在函数说明时定义,也可以在函数实现时定义
D. 派生类的虚函数与基类中对应的虚函数具有相同的参数个数和类型
参考答案:D
2
例题11:分析下列程序的输出结果。
#include <iostream.h>
class A{
public:
A() { cout<<"A's cons."<<endl; }
virtual ~A() { cout<<"A's des."<<endl; }
virtual void f() { cout<<"A's f()."<<endl; } void g() { f(); }
};
class B : public A{
public:
B() { f(); cout<<"B's cons."<<endl; }
3
~B() { cout<<"B's des."<<endl; }
};
class C : public B{
public:
C() { cout<<"C's cons."<<endl; }
~C() { cout<<"C's des."<<endl; }
void f() { cout<<"C's f()."<<endl; }
};
void main()
{ A *a=new C;
a->g();
delete a;
}
4
运行结果:
A's cons.
A's f().
B's cons.
C's cons.
C's f().
C's des.
B's des.
A's des.
10.3 教材习题解答
1.选择题
(1)下列关于动态联编的描述中,错误的是()。
A.动态联编是以虚函数为基础
5
B.动态联编是运行时确定所调用的函数代码的
C.动态联编调用函数操作是指向对象的指针或对象引用
D.动态联编是在编译时确定操作函数的
答案:D
(2)关于虚函数的描述中,正确的是()。
A.虚函数是一个静态成员函数
B.虚函数是一个非成员函数
C.虚函数即可以在函数说明定义,也可以在函数实现时定义
D.派生类的虚函数与基类中对应的虚函数具有相同的参数个数和类型答案:D
(3)下面4个选项中,()是用来声明虚函数的。
A.virtual B.public C.using D.false 答案:A
6
(4)编译时的多态性可以通过使用( )获得。
A.虚函数和指针B.重载函数和析构函数C.虚函数和对象D.虚函数和引用答案:A
(5)关于纯虚函数和抽象类的描述中,错误的是()。
A.纯虚函数是一种特殊的虚函数,它没有具体的实现
B.抽象类是指具体纯虚函数的类
C.一个基类中说明有纯虚函数,该基类派生类一定不再是抽象类
D.抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出
答案:B
(6)下列描述中,()是抽象类的特征。
A.可以说明虚函数B.可以进行构造函数重载C.可以定义友元函数D.不能说明其对象
答案:D
7
(7)以下()成员函数表示虚函数。
A.virtual int vf(int); B.void vf(int)=0;
C.virtual void vf()=0; D.virtual void vf(int) { };
答案:D
(8)如果一个类至少有一个纯虚函数,那么就称该类为( A )。
A.抽象类B.虚函数C.派生类D.以上都不对
答案:A
(9)要实现动态联编,必须通过()调用虚函数。
A.对象指针B.成员名限定C.对象名D.派生类名
答案:A
(10)下面描述中,正确的是(A )。
A.virtual可以用来声明虚函数
8
B.含有纯虚函数的类是不可以用来创建对象的,因为它是虚基类
C.即使基类的构造函数没有参数,派生类也必须建立构造函数
D.静态数据成员可以通过成员初始化列表来初始化
答案:A
2.什么叫做多态性?在C++语言中是如何实现多态的?
答:多态是指同样的消息被不同类型的对象接收时导致完全不同的行为,是对类的特定成员函数的再抽象.c 十+支持的多态有多种类型.重载(包括函数重载和运算符重载)和虚函数是其中主要的方式.
3.什么叫做抽象类?抽象类有何作用?抽象类的派生类是否一定要给出纯虚函数?
答:带有纯虚函数的类是抽象类.抽象类的主要作用是通过它为一个类族建立一个公共的接口.使它们能够更有效地发挥多态特性。
抽象类声明了一组派生类共同操作接口的通用语义.面接口的完整实现,即纯虚函数的函数
9
体,要由派生类自己给出.但抽象类的派生类并非一定要给出纯虚函数的实现.如果派生类没有给出纯虚函数的实现,这个派生类仍然是一个抽象类.
4.声明一个参数为整型、无返回值、名为fun1的虚函数。
答:virtual void fnl(int);
5.在C++语言中,能否声明虚构造函数?为什么?能否声明虚析构函数?有何用途?
答:在C++-中不能声明虚构造函数.多态是不同的对象对同一消息有不同的行为特性.虚函数作为运行过程中多态的基础,主要是针对对象的,面构造函数是在对盘产生之前运行的,因此虚构造函数是没有童义的.在C++中可以声明虚析构函数.析构函数的功能是在该类对象消亡之前进行一些必要的清理工作,如果一个类的析构函数是虚函数,那么,由它派生而来的所有子类的析构函数也是虚函数.析构函数设置为虚函数之后,在使用指针引用时可以动态联编,实理运行时的多态,保证使用基类的指针就能够谓用适当的析构函数指针对不同的对象进行清理工作.
10
10.声明一个Shape抽象类,在此基础上派生出Rectangle和Circle类,二者都有GetArea( )函数计算对象的面积,GetPerim( )函数计算对象的周长。
解答:
#include<iostream.h>
#include<math.h>
class shape
{ public:
virtual void getarea()=0;
virtual void getperim()=0;
};
class rectangle:public shape
{ int a,b,c;
11
double s,p;
public:
rectangle(int a1,int b1,int c1) {a=a1;b=b1;c=c1;} void getperim()
{ p=a+b+c; cout<<"周长 "<<p<<endl;}
void getarea()
{ p=(a+b+c)/2.0;
s=sqrt(p*(p-a)*(p-b)*(p-c));
cout<<"面积"<<s<<endl;
}
};
class circle :public shape
{ float r,s,p;
12
public:
circle(float r1) {r=r1;}
void getperim() { p=2*r*3.1415926;cout<<"周长 "<<p<<endl;}
void getarea() { s=r*r*3.1415926; cout<<"面积"<<s<<endl;} };
void show(shape *p)
{ p->getarea();
p->getperim();
}
void main()
{ shape *p;
rectangle a(3,4,5);
circle b(10);
13
p=&a; show(p);
p=&b; show(p);
}
10.4 补充习题
(6)有如下类的定义。
空格处的语句是()。
class MyClass
{public:
MyClass(int a = 0, int b = 0){ X = a;Y = b; } void Change() const {X -= 10; Y += 10; }
private:
()int X, Y;
};
14
A.static B.const C.mutable D.不需要填入内容
(7)编译时的多态性可以通过使用()获得。
A.虚函数和指针B.重载函数和析构函数C.虚函数和对象D.虚函数和引用
2.填空
(1).单目运算符作为类成员函数重载时形参;双目运算符作为重载时需声明其右操作数,作为重载时需声明全部操作数。
10.根据给定的程序执行结果,将下列程序补充完整。
#include <iostream.h>
class Base
{public:
Base(int i) {b=i;}
15
(1)
protected:
int b;
};
class Derive1:public Base
{public:
(2)
void Print(){cout<<"Derive1's Print() called."<<endl;} };
class Derive2:public Base
{ (3)
};
void fun( (4) ){ obj->Print();}
16
void main()
{ (5)
fun(d1);
fun(d2);
}
程序的执行结果如下:
Derive1's Print() called.
Derive2's Print() called.
#include<iostream.h>
class Base
{public:
Base(int i) {b=i;}
17
virtual void Print(){};
protected:
int b;
};
class Derive1:public Base
{public:
Derive1():Base(1){};
void Print(){cout<<"Derive1's Print() called."<<endl;} };
class Derive2:public Base
{public:
Derive2():Base(1){};
void Print(){cout<<"Derive2's Print() called."<<endl;}
18
};
void fun(Base *obj){obj->Print();}
void main()
{Base *d1=new Derive1;
Base *d2=new Derive2;
fun(d1);
fun(d2);
}
19。