面向对象的程序设计第2阶段练习题答案江南大学Word下载.docx
《面向对象的程序设计第2阶段练习题答案江南大学Word下载.docx》由会员分享,可在线阅读,更多相关《面向对象的程序设计第2阶段练习题答案江南大学Word下载.docx(24页珍藏版)》请在冰豆网上搜索。
![面向对象的程序设计第2阶段练习题答案江南大学Word下载.docx](https://file1.bdocx.com/fileroot1/2022-12/28/bc57403f-c24e-4617-aa10-b95dc9ba893b/bc57403f-c24e-4617-aa10-b95dc9ba893b1.gif)
6.下列描述中,不正确的是()(1分)
A.赋值运算符有时也需要重载
B.在重载增量或减量运算符时,若使用友元函数,则需要使用引用参数
C.在任何情况下,重载运算符既可用友元函数,也可用成员函数
D.若在某自定义类中重载了下标运算符“[]”,则可将该类的类对象当作一个“数组”
7.多继承派生类析构函数释放对象时,()最先调用。
A.派生类自己的析构函数
B.基类的析构函数
C.根基类的析构函数
D.派生类中子对象类的析构函数
8.关于多继承二义性的描述,()是错误的。
A.派生类的多个基类中存在同名成员时,派生类对这个成员访问可能出现二义性
B.由于二义性原因,一个类不能从同一个类中一次以上直接继承
C.使用作用域运算符对成员进行限定可以解决二义性
D.派生类和它的基类中出现同名函数时,派生类对这个成员函数的访问可能出现二义性
9.下面叙述不正确的是()(1分)
A.基类的保护成员在保护派生类中仍然是保护的
B.基类的保护成员在公有派生类中仍然是保护的
C.基类的保护成员在私有派生类中仍然是保护的
D.对基类的保护成员的访问必须是无二义性的类
二多选题(共3题,总分值6分,下列选项中至少有2个或2个以上选项符合题目要求,请在答题卡上正确填涂。
10.下面描述中,()是正确的。
(2分)
A.虚函数是没有实现的函数
B.纯虚函数的实现是在派生类中定义
C.抽象类是只有纯虚函数的类
D.抽象类指针可以指向不同的派生类
11.假设Myclass为抽象类,下列声明()是错误的。
A.Myclass&func(int);
B.Myclass*pp:
C.intfunc(Myclass);
D.MyclassObj;
12.继承是()的方法。
A.将特殊的类变成通用的类
B.把通用的参数传送给特殊的类的对象
C.将通用的类变成特殊的类
D.将已有的类添加新的特性,但不重写它们
三判断题(共7题,总分值7分正确的填涂“A”,错误的填涂“B”。
13.对下标运算符“[]”,既可重载为类成员函数,可重载为友元函数。
(1分)(
14.无论哪种派生方式,基类中的私有成员在派生类中都是不可访问的。
15.一个类中的虚函数说明不仅对基类中的同名函数有影响,而且对它的派生类中重定义的函数也有影响。
16.如果没有为派生类指定构造函数,则派生类的对象会调用基类的构造函数。
17.在单继承中,派生类对象对基类成员函数的访问也可能出现二义性。
18.重载运算符需要的参数的个数与操作数一样多。
19.构造函数和析构函数都不能说明为虚函数。
四填空题(共10题,总分值20分)
20.在一个继承结构中,解决二义性的方法有_________________和_________________。
21.C++的两种继承方式为
_________________和_________________。
22.运算符函数必须被重载为_________________,或被重载为_________________。
23.类X中的名字N支配类Y中同名的名字N,是指类X以类Y为它的一个基类,这称为_________________。
24.从基类中公有派生一个类时,基类的公有成员就成为派生类的_________________成员,而这个基类的保护成员就成为派生类的_________________成员。
25.对于包含有纯虚函数的类称为_________________。
26.在构造函数和析构函数中调用虚函数时采用_________________联编。
27.重载赋值运算符时,通常返回调用该运算符的_________________,这样赋值就能进行连续。
28.C++支持两种多态性,静态联编所支持的多态性被称为_________________,动态联编所支持的多态性被称为_________________。
29.为了区分重载函数,把一个派生类中重定义基类的虚函数称为_________________。
五简答题(共7题,总分值28分)
30.简述赋值兼容规则。
(4分)
31.简述继承方式下创建对象时构造函数调用的顺序,以及删除对象时析构函数的调用顺序。
32.赋值运算符重载函数与拷贝构造函数有什么区别?
33.虚函数与一般重载函数有哪些区别?
34.简述派生类构造函数的规则。
35.能否声明虚析构函数?
有何用途?
36.重载前缀“++”运算符与重载后缀“++”运算符在形式上有什么不同?
六综合题(共5题,总分值30分)
37.#include<iostream>
usingnamespacestd;
classA
{
public:
A(inti,intj){a=i;
b=j}//基类构造函数
voidmove(intx,inty){a+=x;
b+=y;
}
voiddisp()
cout<<"
("
<<a<<"
,"
<<b<<"
)"
<<endl;
private:
inta,b;
};
classB:
publicA
B(inti,intj,intk,intl):
A(i,j),x(k),y(l){}//派生类构造函数
cout<<x<<"
<<y<<endl;
voidfun1(){move(13,15);
voidfun2(){A:
:
disp();
}//语句8
intx,y;
intmain()
Aaa(11,12);
//语句1
aa.disp();
//语句2
Bbb(13,14,15,16);
//语句3
bb.fun1();
//语句4
bb.A:
//语句5
bb.B:
//语句6
bb.fun2();
//语句7
return0;
//语句8
}(6分)
38.编写一个程序,用于计算正方形、三角形和圆的面积及计算各类形状的总面积。
(6分)
39.
(1)在C++中,分数不是预先定义的,需要建立一个分数类,使之具有下述功能:
能防止分母为0,当分数不是最简形式时进行约分以及避免分母为负数。
用重载运算符完成加法、减法、乘法以及除法等四则运算。
40.在第
(1)题的基础上,用重载关系符“==”判断两个分数是否相等。
41.定义一个点类(Point)、矩形类(Rectangle)和立方体类(Cube)的层次结构。
矩形包括长度和宽度两个新数据成员,矩形的位置从点类继承。
立方体类由长度、宽度和高度构成。
要求各类提供支持初始化的构造函数和显示自己成员的成员函数。
编写主函数,测试这个层次结构,输出立方体类的相关信息。
1.正确的答案是:
B
解析过程:
在派生类中新定义虚函数时,要求与基类中说明的虚函数的原型完全相同。
2.正确的答案是:
C
私有成员是被隐藏的数据,只有该类的成员函数或友元函数才可以引用它。
3.正确的答案是:
A声明的func()为一个错误的函数;
C声明的func()为虚函数;
D声明的func为空的虚函数。
4.正确的答案是:
重载运算符能改变运算符操作的类型,且通常改为自定义的类类型。
5.正确的答案是:
D
动态联编需要满足3个条件,首先类之间满足类型兼容规则,其次是要声明虚函数,再次是要由成员函数来调用或者是通过指针、引用来访问虚函数
6.正确的答案是:
在一般情况下,重载运算符既可用友元函数,也可用成员函数。
有时将二元运算符重载为友元函数比重载为成员函数使用起来更灵活同样,重载为友元函数也有一些限制如友元函数不能重载()、[]、->、=、+=、和-=等运算符
7.正确的答案是:
A
8.正确的答案是:
派生类和它的基类中出现同名函数时,派生类对这个成员函数的访问采用支配规则,不可能出现二义性。
9.正确的答案是:
基类的保护成员在私有派生类中变为私有的。
10.正确的答案是:
B,D
被关键字virtual说明的成员函数为虚函数。
它有函数实现,即使函数体可能为空。
只要一个类中含有纯虚函数,该类即为抽象类。
根据赋值兼容规则,抽象类指针可以指向不同的派生类。
11.正确的答案是:
C,D
一个抽象类只能作为基类来派生新类。
不能说明抽象类的对象,因为抽象类中有一个或多个函数没有定义。
也不能用做参数类型、函数返回类型或显式类型转换,但可以说明指向抽象类对象的指针(和引用),以支持运行时多态性。
12.正确的答案是:
继承常用来表示类属关系,还可以用来描述派生类与基类之间特殊与一般的关系。
当从现存类中派生出新类时,可以对派生类做如下几种变化,但并不改变基类本身
◆可以增加新的成员变量。
◆可以增加新的成员函数。
◆可以重新定义已有的成员函数。
◆可以改变现有成员的属性。
13.正确的答案是:
F
对下标运算符“[]”进行重载,只能重载为类成员函数,不可重载为友元函数
14.正确的答案是:
T
15.正确的答案是:
一个类中的虚函数说明只对派生类中重定义的函数有影响,对它的基类中的函数并没有影响。
16.正确的答案是:
无论是否为派生类指定构造函数,派生类的对象都会调用基类的构造函数。
如果没有为派生类指定构造函数,则派生类的对象会调用基类的默认构造函数。
17.正确的答案是:
在单继承中,即使派生类和它的基类中出现同名函数时,派生类对这个成员函数的访问也会采用支配规则,所以派生类对象对基类成员函数的访问不可能出现二义性。
18.正确的答案是:
一般来说,用友元函数重载运算符需要的参数的个数与操作数的个数一样多,而用成员函数重载运算符需要的参数的个数总比它的操作数的个数少一个
19.正确的答案是:
构造函数不能说明为虚函数,但析构函数可以说明为虚函数。
20.正确的答案是:
使用作用域运算符,引进虚基类。
21.正确的答案是:
单继承,多继承
22.正确的答案是:
非静态成员函数,友元函数
23.正确的答案是:
支配规则
24.正确的答案是:
公有,保护
25.正确的答案是:
抽象类
26.正确的答案是:
静态
27.正确的答案是:
对象的引用
28.正确的答案是:
编译时的多态性,运行时的多态性
29.正确的答案是:
覆盖
30.正确的答案是:
所谓赋值兼容规则是指在公有继承情况下,一个派生类的对象可以作为基类的对象来使用。
具体来说,就是下面3种情况。
◆派生类的对象可以赋给基类的对象。
◆派生类的对象可以初始化基类的引用。
◆派生类的对象的地址可以赋给指向基类的指针。
31.正确的答案是:
继承方式下创建对象时,首先基类构造函数被调用,子对象所在类构造函数次之,最后执行派生类构造函数。
删除对象时析构函数的调用顺序正好与之相反。
32.正确的答案是:
拷贝构造函数和赋值运算符重载函数都是用来拷贝一个类的对象给另一个同类型的对象。
要注意拷贝构造函数与赋值运算符重载函数的使用区别。
①拷贝构造函数是用已存在对象的各成员当前值来创建一个相同的新对象。
在下述3种情况下,系统将自动调用所属类的拷贝构造函数。
◆当说明新的类对象的同时,要给它赋值另一个已存在对象的各成员当前值
◆当对象作为函数的赋值参数而对函数进行调用要进行实参和形参的结合时
◆当函数的返回值是类的对象,在函数调用结束后返回到主调函数处时
②赋值运算符重载函数要把一个已存在对象的各成员当前值赋值给另一个已存在的同类对象。
33.正确的答案是:
虚函数与一般重载函数主要有下面几点区别:
◆重载函数只要求函数有相同的函数名,并且重载函数是在相同作用域中定义的名字相同的不同函数;
而虚函数不仅要求函数名相同,而且要求函数的签名、返回类型也相同。
也就是说函数原型必须完全相同,而且虚函数特性必定是体现在基类和派生类的类层次结构中。
◆重载函数可以是成员函数或友元函数;
而虚函数只能是非静态成员函数。
◆构造函数可以重载,析构函数不能重载。
正好相反,构造函数不能定义为虚函数,而析构函数能定义为虚函数。
◆重载函数的调用是以所传递参数序列的差别作为调用不同函数的依据,而虚函数是根据对象的不同去调用不同类的虚函数。
◆重载函数在编译时表现出多态性,是静态联编;
而虚函数则在运行时表现出多态性是动态联编。
34.正确的答案是:
◆若派生类有构造函数而基类没有,当创建派生类的对象时,派生类相应的构造函数被自动调用。
◆若派生类没有构造函数而基类有,则基类必须拥有默认构造函数。
只有这样,当创建派生类的对象时,才能自动执行基类的默认构造函数。
◆若派生类有构造函数,且基类有默认构造函数,则创建派生类的对象时,基类的默认构造函数会自动执行,除非当前被调用的派生类构造函数在其初始化段中显式地调用了基类的有参构造函数。
◆若派生类和基类都有构造函数,但基类没有默认构造函数时,则派生类的每一个构造函数必须在其初始化列表中显式地调用基类的某个构造函数。
只有这样,当创建派生类的对象时,基类的构造函数才能获得执行机会。
35.正确的答案是:
能声明虚析构函数。
如果一个类的析构函数是虚函数,那么,由它派生而来的所有子类的析构函数也是虚函数。
delete运算符和析构函数一起工作,当使用delete删除一个对象时,delete隐含着对析构函数的一次调用;
如果析构函数为虚函数,则这个调用采用动态联编。
这样保证了基类类型的指针能够调用适当的析构函数针对不同的对象进行清理工作。
36.正确的答案是:
增量运算符“++”既可以按成员函数方式重载也可以按友元函数方式重载,而且既可被重载为前缀运算符,也可被重载为后缀运算符。
其中后缀运算符函数多给出一个int型参数,表明调用该函数时运算符“++”应放在操作数的后面,且并不在函数体中使用该参数本身,因此没有必要给出该参数的名字
①用成员函数形式重载运算符++。
以成员函数方式重载前缀“++”运算符的函数原型的一般格式如下
<类型><类名>:
operator++();
以类成员方式重载后“++”运算符的函数原型的一般格式如下:
operator+(int);
②用友元函数形式重载运算符++
如果要用友元函数重载增量++,必须把操作数作为引用参数传递。
以友元函数方式重载前缀“++”运算符的函数原型一般格式如下:
<类型>operator++(<类名>&
);
以友元方式重载后缀“++”运算符的函数原型一般格式如下:
,int)
37.正确的答案是:
【输出结果】
(11,12)
(26,29)
15,16
①程序执行语句1,调用基类构造函数,使得aa.a和aa.b的值分别为11和12,执行语句2时,输出第1行结果。
②程序执行语句3时,首先调用基类构造函数,初始化成员列表,然后调用派生类构造函数,使得b.a、bb.b、bb.x和bb.y的值分别为13、14、15和16。
③程序执行语句4时,使得bb.a和bb.b的值分别为26和29。
④程序执行语句5和语句6时,分别调用基类和派生类中的disp(),输出第2行和第3行结果。
⑤程序执行语句7时,输出第4行结果。
注意:
由于支配性规则,语句5和语句8必须用类名加作用域运算符进行限定,否则结果是不一样的,读者可以自己上机试一试。
38.正确的答案是:
//xt5_2.cpp
#include<iostream>
#include<string>
classShape//定义抽象类Shape
public:
shape();
//构造函数,计算图像序号
voidshow();
//输出面积
virtualdoublearea()=0;
//纯虚函数,计算面积
virtualstringshapename()=0;
//纯虚函数,得到显示图形的名称
protected:
stringname;
staticintcount;
//记录图形序号
Shape:
shape()
请输入"
;
count=count+1;
voidShape:
show()
第"
<<count<<"
个图形是"
<<shapename();
,面积为"
<<area()<<endl;
doubletotal(Shape*s[],intn)//全局函数,计算所有图形的总面积
doublesum=0;
for(inti=0;
i<n;
i++)
sum+=s[i]->area();
deletes[i];
returnsum;
classTriangle:
publicShape/定义派生类Triangle
Triangle();
//构造函数,得到三角形的底和高
doublearea(){retrunh*w*0.5;
}//纯虚函数的具体实现,计算三角形的面积
stringshapename(){name="
三角形"
returnname;
}//得到三角形的名称
doubleh,w;
Triangle:
Triangle()
oublemyw,myh;
三角形的底和高"
cin>>myw>>nyh;
h=myh;
classRectangle:
publicShape//定义派生类Rectangle
Rectangle();
//构造函数,得到矩形的长和宽
doublearea(){returnl*w;
}//纯虚函数的具体实现,计算矩形的面积
矩形"
}//得到矩形的名称
doublel,w;
Rectangle:
Rectangle()
doublemyl,myw;
矩形的长和宽"
cin>>myl>>myw;
l=myl;
w=myw;
classCircle:
publicShape//定义派生类Circle
Circle();
//构造函数,得到圆的半径
doublearea(){returnradius*radius*3.14;
}//纯虚函数,计算圆的面积
圆"
}//得到圆的名称
doubleradius;
Circle:
Circle()
doubler;
圆的半径:
"
cin>>r;
radius=r;
intShape:
count=0;
Shape*s[4];
s[0]=newTriangle();
s[0]->show();
s[1]=newRectangle();
s[1]->show();
s[2]=newCircle();
s[2]->show();
s[3]=newCircle();
s[3]->show();
doublesum=total(s,4);
上述图形的面积和为:
cout<<sum<<endl;
请输入三角形的底和高:
34
第1个图形是三角形,面