c++含详细答案 期末考试用试题四.docx
《c++含详细答案 期末考试用试题四.docx》由会员分享,可在线阅读,更多相关《c++含详细答案 期末考试用试题四.docx(11页珍藏版)》请在冰豆网上搜索。
![c++含详细答案 期末考试用试题四.docx](https://file1.bdocx.com/fileroot1/2023-1/23/b8ac4955-a1eb-4f12-9683-bb6790a4e26d/b8ac4955-a1eb-4f12-9683-bb6790a4e26d1.gif)
c++含详细答案期末考试用试题四
c++含详细答案期末考试用试题四
《试题四》
一、单选题(共10分,每题1分)
1.C++中解决命名冲突的机制是:
(A)虚基类(B)虚函数(C)函数重载(D)名字空间2.若类A的一个对象所占的内存空间中包含虚函数表的入口地址,则:
(A)类A不能有静态数据成员(B)类A中公有的成员函数一定是虚的
(C)类A中至少有一个成员函数是虚的(D)类A的析构函数一定是虚的3.任意一个类,析构函数的个数最多是:
(A)不限个数(B)1(C)2(D)3
4.下列关于this指针的说法,哪个是正确的:
(A)this指针一定指向常量型数据(B)this指向的数据不可更改
(C)静态成员函数中也可以访问this指针(D)this指针本身可直接作为成员函数的返
回值
5.在类定义中,为说明成员的访问权限,private,protected,public可以出现次数为:
(A)次数没有具体限定(B)每种至多一次
(C)至少一次(D)每种至少一次
6.下面哪种定义方式是正确的,并且使得p可以作为函数voidf(A*constpp);的实参:
(A)A*p=newA;(B)Aa;A*p=a;
(C)constA*p=newA;(D)Aa;constA*p=a;
7.obj是类A的一个对象,执行语句constA&aA=obj;,则下列说法正确的是:
(A)类A的拷贝构造函数会被调用(B)类A的赋值函数会被调用
(C)&aA的值就是&obj(D)语句obj.f();等价于语句aA.f();8.下面关于访问类A的私有数据成员的说法,错误的是:
(A)类A的友元函数可以访问类A的私有成员。
(B)类A的友元类中的非静态成员函数可以访问类A的私有成员。
(C)类A的嵌套类中的非静态成员函数可以访问类A的私有成员。
(D)类A中的非静态成员函数可以访问类A的私有成员。
9.类A中有唯一的一个成员函数f,且f是公有的静态或非静态成员函数,对于类A的一个对象a,执行语句a.f(100);成功,那么f的函数原型不可以是:
(A)A&f(int,int=50);(B)voidf(int&);
(C)constA*f(constint);(D)Af(constint&);
10.下面关于类的成员函数描述不正确的是:
(A)静态成员函数内可以直接访问类的非静态成员数据
(B)静态成员函数内可以直接访问类的静态成员数据
(C)非静态成员函数可以直接访问类的非静态成员数据
(D)非静态成员函数可以直接访问类的静态成员数据
二、判断正误,对于你认为错误的论述,说明原因或举出反例。
(每题2分,共20分)1.重载流操作符<<和>>时,如果第一个参数的类型为ostream和istream,那么这个重载
函数既可以用于标准输入输出流,也可以用于文件流上。
2.在同一个类中,可以定义重载的成员函数voidf(int);和virtualvoidf(int);。
3.抽象类不会产生实例,所以不需要有构造函数。
4.类A有一个非静态的成员函数f,其函数原型是:
voidA:
:
f()const,则该函数被调用时,
一定是通过类A或类A的某后裔类的一个用const修饰符说明的常量对象调用的。
5.异常必须在其产生的当前函数中捕获,而不能在外层函数中捕获该异常。
6.只要程序中没有Aa1=a2;和Aa1(a2);形式的代码,类A的拷贝构造函数就不会被
调用。
7.在protected继承方式下,派生类对象的指针不能直接转换成指向基类对象的指针。
对,否则基类中的公有成员由不可见变为可见,权限被放大
8.若静态成员函数中调用了一个函数f,那么f一定不是虚函数。
9.若要实例化一个含有引用型数据成员的类,那么只能使用构造函数初始化列表来初始化
该数据成员。
10.构造函数的函数体中,不能使用return语句;但在实现该类的自动类型转化函数时,必
须有return语句。
三、回答下列各题(每题4分,共20分)
1.举例说明static关键字的用法和相应目的(至少3种)。
2.举例说明类的数据成员在哪些情况下必须在初始化列表中进行初始化(至少3种)。
3.举例说明虚拟继承的作用和目的。
4.举例说明成员函数A&f()const;和成员函数A&f();的区别。
5.有类A的对象a,任意给出一种解决方案,使得程序支持下面的表达式:
a=10+a;
四、指出下列程序代码中存在的错误或不足,说明原因。
(每题5分,共10分)
1.#include
classA{
public:
virtual~A(){}
virtualvoidf()
{cout<<"A:
:
f()"<virtualvoidg()
{cout<<"A:
:
g()"<classB:
publicA
{
public:
virtualvoidg()
{cout<<"B:
:
g()"<virtualvoidk()
{cout<<"B:
:
k()"<voidmain()
{
A*p=newB;
p->f();
p->g();
p->k();
deletep;
}
2.#include
#include
classA;
classB:
publicA
{
public:
B(constchar*info){
m_buf=newchar[256];
strcpy(m_buf,info);}
~B(){delete[]m_buf;}
virtualvoidoutput(){cout<private:
char*m_buf;
};
classA
{
public:
~A(){}
virtualvoidoutput(){}};
voidmain()
{
A*pa=newB("hello!
");
pa->output();
deletepa;
}
五、写出下面程序的运行结果(每题5分,共10分)
1.#include
classA{
public:
A():
count
(1){}
virtual~A(){}
virtualA*Copy()const=0;
virtualvoidOut()const=0;protected:
intcount;
};
classB:
publicA{
public:
~B(){--count;Out();}
virtualA*Copy()const{
B*p=newB(*this);
++p->count;
returnp;
}
virtualvoidOut()const{cout<};
voidmain()
{
{
Bb;
A*a1=&b;
a1->Out();
a1=a1->Copy();
a1->Out();
deletea1;
}
}
2.#include
classA
{
public:
A(intn):
num(n){Out();}
A(constA&rhs):
num(rhs.num){Out();}
voidOut(){cout<intnum;
};
classB:
publicA
{
public:
B(A&a):
obj(a),A
(1){}
voidOut(){obj.Out();}private:
Aobj;
};
voidmain(){
Aa(8);
Bb1(a);
Bb2(b1);
b2.Out();
}
六、阅读下面两个类的定义和部分实现代码,完成3个问题。
(共10分)
#include
classA
{
public:
A(intn):
value(n){}
voidDisplay()const
{cout<<"Value="<private:
intvalue;
};
classB
{
public:
B(intn);
voidDisplay()const
{aA.Display();}
private:
AaA;
};
intmain()
{
Bb1
(1);
b1.Display();
Bb2
(2);
b2.Display();
return0;
}
1.[3分]实现类B的构造函数,使得程序的输出为:
2.[3分]若main函数中增加了语句Bb3(b1);针对本例,说明是否有必要以公有方式自定
义并实现类B的拷贝构造函数,为什么?
3.[4分]在不改动类A和main函数的前提下,以继承的方式重新定义并实现类B,使得程
序的输出结果不变。
七、(共20分,每问题10分)某程序员为了灵活地对各种的给定的曲线函数f(x)画出其曲线图形,设计并部分实现了一个曲线类curve,该类的成员数据中,count代表坐标点的个数,pxs代表的数组存放这些坐标点的横坐标,pys代表的数组存放利用f(x)计算得到的这些坐标点的纵坐标。
由于不同曲线的计算公式f(x)是不同的,该程序员希望曲线函数的种类可以通
过继承curve类的方式任意增加,增加一个新的f(x)时不改变curve类中的内容,也不改变利用curve类进行图形绘制的算法。
已部分完成的curve类定义和实现如下:
classcurve{
public:
voidsetPxs(){/*把获取的横坐标数据存放在pxs代表的数组中,并为count置值*/}
double*getPxs()const{returnpxs;}
intgetCount()const{returncount;}
double*getPys()const;
private:
double*pxs;
double*pys;
intcount
};
1、请按照该程序员的设计意图给出成员函数getPys的完整实现。
实现过程中,可以为curve
类增加其它成员。
可以假设setPxs函数已经完整实现,不需要考虑曲线的绘制和显示。
2、以曲线函数:
f(x)=3*x*x+2*x+1.为例,从curve派生一个类curve1,并用文字说明其它
的函数(如:
main函数)如何利用基类curve中的getPys函数获取该曲线的纵坐标值。
《试题四答案》一.1.D2.C3.B4.D5.A6.A7.C8.C9.B10.A
二.
1.对,ostream和istream是标准输入输出流、文件流、字符串流的基类
2.错,这属于重复定义
3.错,被派生时需要它的构造函数
4.错,常函数可以由变量对象或常量对象调用
5.错,可以在外层捕获,并且这是最常见的用法
6.错,参数传递或函数返回时也调用拷贝构造函数
7.对,否则基类中的公有成员由不可见变为可见,权限被放大
8.对,静态成员函数不能是虚函数,因为虚函数入口需要在保存在对象中的虚函数
表中,而静态成员函数不属于对象
9.对,没有别的办法
10.对
三.
1.f(){staticinta;…}函数体内的静态变量,每次调用该函数时值保持不变
staticinta;全局的静态变量,约束作用域为所在文件
classA{staticinta;…};A的静态成员,类似全局变量,需用A:
:
a访问
2.基类不提供无参的构造函数
成员对象不提供无参的构造函数
有常量成员或引用成员
3.虚拟继承的目的是使基类在派生类中只保留一个副本
从而避免二义性
4.A&f()const是常函数,隐含的this指针是常指针,因此在f中不能修改对象成
员的值。
举例略
5.classA
{
A(int);//转换构造函数
friendconstAoperator+(constA,constA);//重载+
};
四.
1.函数k在A中没有定义,执行p->k();时要根据p的类型在A中查k的信息2.A的析构函数应定义为虚函数,否则B的析构函数不会被调用,m_buf也不会被释放
五.
1.
1
2
1
0
2.
8
1
8
1
8
8
六.
1.B(intn):
aA(n)
2.不需要,因为类B及基类A中不存在引用或指针成员,使用默认的拷贝构造函数就可以。
3.classB:
publicA
{
public:
B(intn):
A(n);
voidDisplay()const
{
A:
:
Display();
}};
七.
1.
classcurve{
public:
voidsetPxs(){/*把获取的横坐标数据存放在pxs代表的数组中,并为count置值*/}
double*getPxs()const{returnpxs;}
intgetCount()const{returncount;}
double*getPys()const;
virtualdoublef(double)=0;
private:
double*pxs;
double*pys;
intcount
};
double*curve:
:
getPys()const
{
if(pys==NULL)pys=newdouble[count];
for(inti=0;ipys[i]=f(pxs[i]);
returnpys;
}
注:
严格来讲,还应在析构函数中释放pxs和pys,但这部分不作为要考的语法点,
故此处略掉
2.
classcurve1:
publiccurve
{
virtualdoublef(doublex){return3*x*x+2*x+1;}};