C复习题8Word格式文档下载.docx
《C复习题8Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《C复习题8Word格式文档下载.docx(15页珍藏版)》请在冰豆网上搜索。
(8)派生类中对基类的虚函数进行替换时,派生类中说明的虚函数与基类中的被替换的虚函数之间不要求满足的是(C)。
A)与基类的虚函数具有相同的参数个数。
B)其参数的类型与基类的虚函数的对应参数类型相同。
C)基类必须定义纯虚函数。
D)其返回值或者与基类的虚函数相同,或者都返回指针或引用,并且派生类虚函数所返回的指针或引用的基类型是基类中被替换的虚函数所返回的指针或引用的基类的子类型。
(9)下列关于抽象类说法正确的是:
(B)
A)抽象类处于继承类层次结构的较下层。
B)抽象类刻画了一组子类的操作通用接口。
C)抽象类可以作为类直接使用。
D)抽象类可以直接定义对象。
(10)下列关于虚析构函数说法不正确的是(B)。
A)在析构函数前加上关键字virtual,就说明了虚析构函数。
B)如果一个基类的析构函数说明为虚析构函数,则它的派生类中的析构函数须用virtual关键字说明后才是虚析构函数。
C)说明虚析构函数的目的在于使用delete删除一个对象时,能保证析构函数被正确地执行。
D)设置虚函数后,可以采用动态联编的方式选择析构函数。
(11)编译时多态性通过使用(B)获得。
A)继承B)虚函数C)重载函数D)析构函数
(12)可以使用(A)来阻止基类的成员函数调用派生类中的虚函数。
A)成员名限定B)指针C)引用D)关键字virtual
(13)抽象类应该含有(D)。
A)至多一个虚函数B)至多一个虚函数是纯虚函数
C)至少一个虚函数D)至少一个虚函数是纯虚函数
(14)一个抽象类可以说明为(A)。
A)指向抽象类对象的指针B)类成员数据C)抽象类的对象D)数组元素
(15)对于抽象类的使用需要注意的地方,下列不正确的说法是:
(C)
A)抽象类只能用作其它类的基类,不能建立抽象类对象。
B)抽象类不能用作参数类型,函数返回类型或显式转换的类型。
C)定义抽象类时至少要定义一个虚函数。
D)可以说明指向抽象类的指针和引用,此指针可以指向它的派生类,进而可以实现多态性。
(16)关于动态联编的说法,下列哪个不正确?
A)动态联编只能通过指针或引用标识对象来操作虚函数。
B)C++使用虚函数来指定哪些函数需要用动态联编方式处理。
C)动态联编不能实现静态类型检查。
D)动态联编能够在运行时根据其类型确认调用哪个函数。
(17)将一个类的成员函数尽可能地设置成虚函数总是有益的,下列设置虚函数必须注意的情况中,哪个是错误的?
(D)
A)只有类的成员函数才能说明为虚函数。
B)静态成员函数不能是虚函数。
C)构造函数不能是虚函数。
D)析构函数不能是虚函数。
(18)在派生类中重新定义虚函数时必须在(A)方面与基类保持一致。
A)参数个数B)赋值C)参数名字D)操作内容
(19)以下哪个基类中的成员函数表示纯虚函数(C)。
A)virtualvoidvf(int)B)voidvf(int)=0;
C)virtualvoidvf()=0D)virtualvoidvf(int){}
(20)通过一个对象调用虚函数时,C++系统对该调用采用(B)。
A)动态联编B)静态联编C)不确定是哪种联编D)函数重载
参考答案:
CCCACDDCBBBADACCDACB
二.判断正误
(1)函数参数个数和类型都相同,只是返回值类型不同,这不是重载函数。
(×
)
(2)虚函数是为实现某种功能而假设的函数,派生类的虚函数定义影响其基类,而基类的虚函数定义不影响其派生类。
(3)可以在类的内部说明虚函数,这时就可以定义一个虚的内联函数。
(√)
(4)空的虚函数与纯虚函数都没有函数体,因此空的虚函数与纯虚函数在概念上是一样的,只是叫法不一样。
(5)只要基类的析构函数被说明为虚函数,则派生类的析构函数,无论是否使用virtual进行说明,都自动地成为虚构函数。
(6)虚函数是一种virtual说明的成员函数。
(7)抽象类中只能有一个纯虚函数。
(8)析构函数不能说明为虚函数。
(9)程序中可以说明抽象类的指针或引用,但是不能说明抽象类的对象。
×
√×
√√×
√
三.分析程序运行结果
1.#include<
iostream.h>
classbase
{
public:
base(void){fc();
}
virtualvoidfc(void){cout<
<
"
Inclassbase"
endl;
virtual~base()=0{cout<
Destructingbaseobject..."
};
classA:
publicbase
A(void){fc();
voidf(void){fc();
~A(void){fd();
voidfd(void){cout<
DestructorAobject..."
classB:
publicA
B(void){};
voidfc(void){cout<
InclassB"
endl;
~B(void){fc();
DestructorBobject"
voidmain(void)
Bb;
/*
由于B类是A类的子类,A类是base类的子类,
所以先调用base类的构造函数,再调用A类和B类的构造函数*/
cout<
b.fc();
//动态联编,调用B类的fc()函数
base*p=newA;
//先调用base类构造函数,再调用A类的构造函数deletep;
//先调用A类的析构函数,再调用base类的析构函数
//释放对象b所占有的空间,分别调用BAbase类的析构函数
Inclassbase
InclassB
DestructorAobject...Destructingbaseobject...
(2)#include<
classC;
classA
public:
inta;
A(inti){a=i;
virtualvoidprintOn(C&
);
intb;
B(inti,intj):
A(i){b=j;
classC
friendvoidA:
:
printOn(C&
friendvoidB:
inta,b,c;
C(inti,intj,intk){a=i;
b=j;
c=k;
}};
voidA:
t)
ClassAmembera="
a<
ClassCmemberc="
t.c<
voidB:
ClassBmemberb="
b<
t.c<
voidmain()
//考查内容:
指向基类对象的指针,可以指向其子类对象,
//使用指针调用成员函数时,根据对象不同而调用基类与其子类中相应的同名函数
Aa(10);
Bb(10,20);
Cc(10,20,30);
A*p;
p=&
a;
p->
printOn(c);
b;
ClassAmembera=10
ClassCmemberc=30
ClassBmemberb=20
(3)#include<
virtualvoida(){cout<
a()inbase\n"
;
virtualvoidb(){cout<
b()inbase\n"
virtualvoidc(){cout<
c()inbase\n"
virtualvoidd(){cout<
d()inbase\n"
virtualvoide(){cout<
e()inbase\n"
virtualvoidf(){cout<
f()inbase\n"
a()inA\n"
b()inA\n"
f()inA\n"
a()inB\n"
b()inB\n"
c()inB\n"
classC:
publicA,publicB
a()inC\n"
d()inC\n"
Ccc;
A*pa=&
cc;
pa->
a();
//C类中有a(),调用
b();
//C类中没有b(),从其基类中寻找,先从A类中找,有则调用,无有则从B类中寻找
c();
//C类中没有c(),从其基类A和B中寻找,先从A类及其基类中找,有则调用;
若无,则从B类及其基类中寻并调用
d();
//C类中有d(),调用
e();
//C类中没有e(),先从A类及其基类base中寻找,从base中找到,调用pa->
f();
//C类中没有f(),先从A类及其基类base中寻找,在A类中找到并调用//考查内容:
多态性,指向基类对象的指针可以指向其子类对象
//这种指针调用函数时先从子类中寻找,如果有则调用,如果没有则从基类中寻找
a()inC
b()inA
c()inbase
d()inC
e()inbase
f()inA
(4)#include<
stdio.h>
#include<
classA{
A(){}
virtualvoidfunc(){cout<
ConstructingA"
~A(){}
virtualvoidfund(){cout<
DestructorA"
B(){func();
virtualvoidfunc(){cout<
ConstructingB"
voidfun(){func();
~B(){fund();
publicB
C(){}
voidfunc(){cout<
ClassC"
~C(){fund();
voidfund(){cout<
DestructorC"
Cc;
//分别调用ABC类的构造函数
c.fun();
//先从C类中查找,没有则从其直接基类B中查找,找到并调用
//构造函数调用函数CBA
ConstructingB
ClassC
DestructorC
DestructorA
(5)#include<
#include<
string.h>
char*p;
base(intsz,char*bptr)
p=newchar[sz];
strcpy(p,bptr);
constructorbase"
virtual~base()
delete[]p;
cout<
"
destructorbase\n"
classderive:
publicbase
char*pp;
derive(intsz1,intsz2,char*bp,char*dptr):
base(sz1,bp){
pp=newchar[sz2];
strcpy(pp,dptr);
constructorderive"
~derive()
delete[]pp;
destructorderive\n"
base*px=newderive(5,7,"
base"
"
derive"
deletepx;
constructorbase
constructorderive
destructorderive
destructorbase
四.指出下列程序中的错误
virtualvoidf1()
{cout<
A:
f1()"
}
virtualvoidf2()
{cout<
f2()"
}};
structB:
A
{voidf1()
B:
voidf2(inti)
f2()"
i<
}};
{A*p;
p=newA;
f1();
p->
f2();
p=newB;
f2(3);
void(A:
*pa)()=A:
f1;
*pa();
deletep;
b.f2();
五.程序设计
(1)定义一个Shape类为抽象类,其中定义一个求面积的纯虚函数,从它派生出三角形(triangle)、矩形(rectangle)、圆(circle)三个子类,每个子类有各自不同的计算面积的公式:
三角形(底*高*0.5)、矩形(长*宽)、圆(3.14*R*R)。
写一个计算不同几何图形总面积的函数,并在main()函数中定义几个子类对象以验证该函数。