一、单项选择题
1.C++是一种(B)的程序设计语言。
A.面向对象B.即可面向过程,又可面向对象
C.面向过程D.面向系统
2.在下面有关析构函数特征的描述中,正确的是(C)。
A.一个类中可以定义多个析构函数B.析构函数名与类名完全相同
C.析构函数不能指定返回类型D.析构函数可以有一个或多个参数
3.下面对于友元函数描述正确的是(C)。
A.友元函数的实现必须在类的内部定义
B.友元函数是类的成员函数
C.友元函数破坏了类的封装性和隐藏性
D.友元函数不能访问类的私有成员
4.下面描述中,表达错误的是(C)。
A.公有继承时基类中的public成员在派生类中仍是public的
B.公有继承时基类中的private成员在派生类中仍是private的
C.公有继承时基类中的protected成员在派生类中仍是protected的
D.保护继承时基类中的public成员在派生类中是private的
5.所谓多态性是指(B)
A.不同的对象调用不同名称的函数B.不同的对象调用相同名称的函数
C.一个对象调用不同名称的函数D.一个对象调用不同名称的对象
6.重载赋值操作符时,应声明为(C)函数。
A.友元B.虚C.成员D.多态
7.下列对模板的声明错误的是(B)。
A.templateclassT1,typenameT2B.templateclassT1,T2
C.templatetypenameTD.templateclassT1,classT2,classT3
8.下列类中(D)不是输入流类istream的派生类。
A.ifstreamB.istrstreamC.iostreamD.ofstream
9.(D)不是构造函数的特征。
A.构造函数的函数名与类名相同B构造函数可以重载
C.构造函数可以设置缺省参数D构造函数必须指定类型说明
10.下列语句中错误的是(D)。
A.int*p=newint(10);B.int*p=newint[10];
C.int*p=newint;D.int*p=newint[40](0)
11.下列关于虚基类的描述,错误的是(B)
A.设置虚基类的目的是为了消除二义性
B.虚基类的构造函数在非虚基类之后调用
C.若同一层中包含多个虚基类,这些虚基类的构造函数按它们说明的次序调用
D.若虚基类由非虚基类派生而来,则仍然先调用基类构造函数,再调用派生类的构造函数
12.已知:print()函数是一个类的常成员函数,它无返回值,下列表示中,(A)是正确的。
A.voidprint()const;B.constvoidprint();
C.voidconstprint();D.voidprint(const);
13.在下面有关静态成员函数的描述中,正确的是(B)。
A.在静态成员函数中可以使用this指针
B.在建立对象前,就可以为静态数据成员赋值
C.静态成员函数在类外定义时,要用static前缀
D.静态成员函数只能在类外定义
14.在下列关键字中,用于说明类中公有成员的是(A)。
A.publicB.privateC.protectedD.friend
15.以下有关继承的叙述正确的是(B)。
A.构造函数和析构函数都能被继承
B.派生类是基类的组合
C.派生类对象除了能访问自己的成员以外,不能访问基类中的所有成员
D.基类的公有成员一定能被派生类的对象访问
16.将客观实体的特征与行为作为不可分割的整体进行程序设计的方法称为(C)程序设计。
A.面向应用B.面向过程C.面向对象D.面向系统
17.构造函数是在(B)时被执行的。
A.程序编译B.创建对象C.创建类D.程序装入内存
18.静态成员函数仅能访问(A)。
A.静态的数据成员B.非静态的成员函数C.非静态的数据成员D.以上都不对
19.要将类A说明是类B的虚基类,正确的描述是(B)。
A.classvirtualB:publicAB.classB:virtualpublicA
C.virtualclassB:publicAD.classB:publicAvirtual
20.以下基类中的成员函数中表示纯虚函数的是(B)。
A.virtualvoidvf(int);B.virtualvoidvf(int)=0;
C.virtualvoidvf(int=0);D.virtualvoidvf(int){};
21.如有以下函数模板:B
Tmin(Ta,Tb)
{returnab?a:b;}
则函数调用minint(,’b’);返回的结果是(D)。
A.B.98C.bD.d
22.下列格式控制符中不是定义于iostream.h中的是(C)。
A.endlB.hexC.flushD.setw
23.在类的定义中,用于为对象分配内存空间、对类的数据成员进行初始化并执行其他内部管理操作的函数是(D)。
A.友元函数
B.虚函数
C.构造函数D.析构函数
24.下面的类型声明中正确的是(B)。
A.inta[4];B.int*p;C.intq;D.intI,*pp=I;
25.下面对类的构造函数的定义正确的是(A)。
A.voidX::X(参数)B.X::X(参数)
C.intX::X(参数)D.floatX::X(参数)
26.当一个函数无返回值时,函数的类型应定义为(D)。
A.voidB.任意C.intD.无
27.已知类A是类B的友元,类B是类C的友元,则(D)
A.类A一定是类C的友元
B.类C一定是类A的友元
C.类C的成员函数可以访问类B的对象的任何成员
D.类A的成员函数可以访问类B的对象的任何成员
28.执行下面的程序将输出(A)
A.XYB.YXC.XD.Y
#includeiostream.h
classBASE{
charc;
public:
BASE(charn):c(n){}
~BASE(){coutc;}
};
classDERIVED:publicBASE{
charc;
public:
DERIVED(charn):BASE(n+1),c(n){}
~DERIVED(){coutc;}
};
intmain()
{ DERIVED(‘X’);
return0;
}
29.能用友元函数重载的运算符是(A)。
A.+B.=C.[]D.-
30.(A)是析构函数的特征。.
A.一个类中只能定义一个析构函数B.析构函数在对象创建时调用
C.析构函数的定义只能在类体内D.析构函数可以有一个或多个参数
31.C++利用(A)实现面向对象程序设计的封装性。
A.构造数据类型——类B.构造数据类型——枚举
C.类的派生机制D.函数重载与运算符重载
32.在声明类时,下面的说法正确的是(C)。
A.可以在类的声明中给数据成员赋初值
B.数据成员的数据类型可以是register
C.private、public、protected可以按任意顺序出现
D.没有用private、public、protected定义的数据成员是公有成员
33.假设已经有定义constchar*constname=chen;下面的语句中正确的是(D)。
A.name[3]=a;B.name=lin;
C.name=newchar[5];D.coutname[3];
34.要将类A说明是类B的虚基类,正确的描述是( B )
A.classvirtualB:publicAB.classB:virtualpublicA
C.virtualclassB:publicAD.classB:publicAvirtual
35.下列关于纯虚函数的描述中,正确的是(D)。
A.纯虚函数是一种特殊的虚函数,它是个空函数
B.具有纯虚函数的类称为虚基类
C.一个基类中说明有纯虚函数,其派生类一定要实现该纯虚函数
D.具有纯虚函数的类不能创建类对象
36.能用友元函数重载的运算符是(A)。
A.+B.=C.[]D.-
37.下面函数模板定义中不正确的是(A)
A.templateclassTB.templateclassT
TF(Tx){returnT+x;}TF(Tx){returnx+x;}
C.templateclassTD.templateclassT
TF(Tx){returnx*x;}TF(Tx){returnx1;}
二、判断题
1.静态的成员函数没有隐含的this指针,所以它们只能访问静态的数据成员。(√)
2.通过类对象可以访问类中所有的成员。(×)
3.构造函数是可以被派生类继承的。(×)
4.构造函数和析构函数都可以是虚函数。(×)
5.只有类中全部函数都为纯虚函数时,该类才被称为抽象类。(×)
6.对于同一个运算符来说,重载的运算符的优先级比未重载的运算符的优先级高。(×)
7.一个类的友元一定是另一个类的成员函数。(×)
1..当一个函数无返回值时,函数的返回类型应为void。(√)
8.9.new和delete运算符可以被重载。(×)
9.3.在默认参数函数的原型中,所有取缺省值的参数都必须出现在不取缺省值的参数的左边。(×)
10.4.数组中的每个元素它们的类型可以是不同的。(×)
11.5.在C++中,用数组、指针、和引用作为函数参数,都能够将参数值带回。(√)
2.6.类中可以包含各种数据类型的数据成员,但不能有其他类对象。(×
12.)
3.7.一个类的友元一定是另一个类的成员函数。(×
13.)
14.C++编译器不能够区分重载的无参函数和缺省参数的函数。(√)
4.指针和引用都是变量,都占有单独的内存空间。(×
15.)
5.一个类可以定义多个构造函数和多个析构函数。(×
16.)
三、简答题
什么是封装性?请举例说明。所谓数据的封装,就是将数据结构和作用于数据结构上的操作组成一个实体,数据的表示方式和对数据的操作细节被隐藏起来,用户通过操作接口对数据进行操作。对于用户来说,只知道如何通过操作接口对该数据进行操作,而并不知道是如何操作的,也不知道数据是如何表示的,这就是数据的封装。例如我们经常使用的手机,机壳将零件和线路封装了起来,我们在接打电话或收发短信时是通过手机面板上的按键(接口)。
1.
什么是函数重载和运算符重载?为什么要使用重载?(1)函数重载是指一个标识符可同时用于为多个函数命名;
(2)运算符重载是指一个运算符可同时用于多种运算。也就是说,相同名字的函数或运算符在不同的场合可以表现出不同的行为。
(3)使用重载的目的是为了更好地表达行为共享,可以使程序员在只知道操作的一般含义而不知道操作的具体细节的情况下能正确地对某个对象使用一个操作。另外,使用重载的直接益处是减少了程序员记忆操作名字的负担
2.
拷贝构造函数在哪几种情况下被调用?(1)用一个对象初始化另一个对象时;
(2)当用对象作为函数参数传递时;
3.(3)当程序中需要创建临时对象时(如函数返回对象时)。
什么是类?什么是对象?对象与类的关系是什么?(1)类是一组具有共同的属性特征和行为特征的对象的抽象;
(2)对象就是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位,由一组属性和一组行为构成。
(3)类和对象之间的关系是抽象和具体的关系,类是对多个对象进行抽象的结果,对象是类的具体实现。
4.
.什么是类?什么是对象?对象与类的关系是什么?(1)类是一组具有共同的属性特征和行为特征的对象的抽象;
(2)对象就是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位,由一组属性和一组行为构成。
(3)类和对象之间的关系是抽象和具体的关系,类是对多个对象进行抽象的结果,对象是类的具体实现。
5.
.什么是多态性?请举例说明。多态性是面向对象程序的重要特征,它是指不同的对象收到相同的消息时产生不同的行为方式。例如我们同样双击windows系统桌面上的图标时,有的是打开媒体播放器,有的是打开D盘,而有的是关机。
6.
.虚函数是否一定要有virtual关键字?什么叫纯虚函数和抽象类?多态调用需要满足怎样的条件?不一定,派生类覆盖基类的成员函数时,没有virtual关键字,也是虚函数;纯虚函数没有实现,它供派生类覆盖,纯虚函数的一般定义形式为:
virtual返回类型函数名(参数表)=0;
至少含有一个纯虚函数的类称为抽象类,抽象类不能定义对象,只能作为基类;多态调用需要满足的条件:(1)被调用的成员函数是虚函数;(2)用指针或引用调用虚函数。
7.
.简述结构化的程序设计、面向对象的程序设计的基本思想。结构化的程序设计将数据和对数据的操作分离,程序是由一个个的函数组成的,面向对象的程序设计将数据和操作封装在一起,程序是由一个个对象组成的,对象之间通过接口进行通信,它能够较好地支持程序代码的复用。
8.
什么是消息?消息具有什么性质?在面向对象程序设计中,一个对象向另一个对象发出的请求被称为“消息”。消息是一个对象要求另一个对象执行某个功能操作的规格说明,通过消息传递才能完成对象之间的相互请求或相互协作。
9.
若程序员没有定义拷贝构造函数,则编译器自动生成一个缺省的拷贝构造函数,它可能会产生什么问题?当对象含有指针数据成员,并用它初始化同类型的另一个对象时,缺省的拷贝构造函数只能将该对象的数据成员复制给另一个对象,而不能将该对象中指针所指向的内存单元也复制过去。这样,就可能出现同一内存单元释放两次,导致程序运行出错。
10.
四、程序分析题
1.指出下面程序中的1处错误,并说明原因。
#includeiostream.h
classPoint
{
intX,Y;
public:
Point(){X=0;Y=0;}
Point(intx=0,inty=0){X=x;Y=y;}
voiddisplay(){coutX,Yendl;}
};
voidmain()
{
Pointp;
p.display();
}
答:错误位置:Pointp;
错误原因:当生成无参对象时,缺省参数的构造函数和默认参数的构造函数会产生混淆。
2.指出下面程序中的1处错误,并说明原因。
#includeiostream.h
classCTest{
public:
CTest(){x=20;}
private:
intx;
friendvoidfriend_f(CTestfri);
};
voidfriend_f(CTestfri){fri.x=55;}
voidmain()
{
CTestc1,c2;
c1.friend_f(c2);
}
答:错误位置:c1.friend_f(c2);
错误原因:friend_f()是类的友元函数,应直接调用,而不能用调用对象成员的方式
3.写出下面程序的运行结果。
#includeiostream.h
classTest
{
private:
intnum;
public:
Test(intn=0){num=n;num++;}
~Test(){cout”Destructorisactive,number=”numendl;}
};
voidmain()
{
Testx[2];
cout”Exitingmain”endl;
}
答:Exitingmain
Destructorisactive,number=1
Destructorisactive,number=1
4.写出下面程序的运行结果。
#includeiostream.h
classTest{
private:
staticintval;
inta;
public:
staticintfunc();
staticvoidsfunc(Testr);
};
intTest::val=20;
intTest::func()
{val--;returnval;}
voidTest::sfunc(Testr)
{r.a=25;coutResult3=r.a;}
voidmain()
{
coutResultl=Test::func()endl;
Testa;
coutResult2=a.func()endl;
Test::sfunc(a);
}
答:Resultl=19
Result2=18
Result3=25
5.指出下列程序中的1处错误,并说明为什么。
classLocation{
intX,Y=20;
protected:
intzeroX,zeroY;
intSetZero(intZeroX,intZeroY);
private:
intlength,height;
public:
voidinit(intinitX,intinitY);
intGetX();
intGetY();
};
答:错误语句:intX,Y=20;
错误原因:数据成员不能在类定义中初始化
6.指出下列程序中的1处错误,并说明为什么。
#includeiostream.h
#includestdlib.h
classCTest{
public:
constinty2;
CTest(inti1,inti2,inti3):y1(i1),y2(i2)
{x=i3;}
intshow()const{couty1=y1\ny2=y2\nx=xendl;}
//…
private:
intx;
constinty1;
};
voidmain()
{
CTestc(1,2,3);
c.show();
c.y2=-2;
c.show();
}
答:错误位置:c.y2=-2;
错误原因:y2是常数据成员,而常数据成员的值是不能被改变的。
7.写出下面程序的输出结果。
#includeiostream.h
classB
{intb;
public:
B(inti){b=i;}
virtualvoidvirfun(){coutB::b:b,;}
};
classD:publicB
{public:
D(inti,intj):B(i){d=j;}
voidvirfun(){B::virfun();coutD::d:dendl;}
private:intd;
};
voidfun(B*objp){objp-virfun();}
voidmain(){D*pd=newD(3,5);fun(pd);}
答:程序输出结果为:
B::b:3,D::d:5
8.写出下面程序的运行结果。
#includeiostream.h
classexample
{
public:
example(intn)
{
i=n;
coutConstructing\n;
}
~example()
{coutDestructing\n;}
intget_i()
{returni;}
private:
inti;
};
intsqr_it(exampleo)
{returno.get_i()*o.get_i();}
main()
{
examplex(10);
coutx.get_i()endl;
coutsqr_it(x)endl;
return0;
}
答:程序输出结果为:
Constructing
10
Destructing
Destructing
9.指出下列程序中的错误,并说明原因。
classA{
inta,b;
public:
A(intaa=0,intbb)
{
a=aa;b=bb;
}
};
答:错误位置:A(intaa=0,intbb){
错误原因:函数的默认参数应从右至左提供
10.指出下面程序中的错误,并说明原因。
#includeiostream.h
classCTest{
public:
CTest(){x=20;}
voiduse_this(int);
private:
intx;
};
voidCTest::use_this(intx)
{
this.x=x;
coutx=xendl;
}
voidmain()
{
CTesty;
y.use_this(10);
}
答:错误位置:this.x=x;
错误原因:用this指针访问对象的数据成员时应使用指针访问运算符“-”,即this-x=x;
五、完成程序题
1.请在横线处填上适当的字句,以使程序完整。
#includeiostream.h
#include″math.h″
classPoint
{
private:
doubleX,Y;
①__________Line;
public:
Point(doublex=0,doubley=0)
{X=x;Y=y;}
Point(Pointp)
{X=p.X;Y=p.Y;}
};
classLine
{
private:
Pointp1,p2;
public:
Line(Pointxp1,Pointxp2):②__________{}
doubleGetLength();
};
doubleLine::GetLength()
{
doubledx=p2.X-p1.X;
doubledy=p2.Y-p1.Y;
returnsqrt(dx*dx+dy*dy);
}
voidmain()
{
Pointp1,p2(3,4);
LineL1(p1,p2);
coutL1.GetLength()endl;
}
(1)friendclass
(2)p1(xp1),p2(xp2)
2.设计一个立方体类Box,使它能计算并输出立方体的体积和表面积。
要求:
Box类包含三个私有数据成员:a(立方体边长)、volume(体积)和area(表面积);
Box类包含有构造函数及seta()(设置立方体边长)、getvolume()(计算体积)、getarea()(计算表面积)和disp()(输出体积和表面积)。
#includeiostream.h
classBox
{
floata;
floatvolume;
floatarea;
public:
Box(){}
Box(floatr){a=r;}
voidseta(floatr){a=r;}
voidgetvolume(){volume=a*a*a;}
voidgetarea(){area=6*a*a;}
voiddisp(){cout体积:volume,表面积:areaendl;}
};
voidmain()
{
Boxobj1(4.5),obj2;
obj2.seta(6.4);
obj1.getvolume();
obj1.getarea();
coutobj1=;
obj1.disp();
obj2.getvolume();
obj2.getarea();
coutobj2=;
obj2.disp();
}
3.请在下面程序的横线处填上适当内容,以使程序完整,并使程序的输出为5。
#includeiostream.h
classInteger
{
intx;
public:
Integer(inta=0){x=a;}
voiddisplay(){coutxendl;}
①
;
};
IntegerMax(Integera,Integerb)
{
if(②
)
returna;
returnb;
}
voidmain()
{
Integera(3),b(5),c;
c=Max(a,b);
c.display();
}
(1)friendIntegerMax(Integera,Integerb);
(2)a.xb.x
4.设计一个三角形类Triangle,包含三角形三条边长的私有数据成员,另有一个重载运算符“+”,以实现求两个三角形对象的面积之和。
#includeiostream.h
#includemath.h
classTriangle
{
intx,y,z;
doublearea;
public:
Triangle(inti,intj,intk)
{
doubles;
x=i;y=j;z=k;
s=(x+y+z)/2.0;
area=sqrt(s*(s-x)*(s-y)*(s-z));
}
voiddisparea()
{coutArea=areaendl;}
frienddoubleoperator+(Trianglet1,Trianglet2)
{returnt1.area+t2.area;}
};
voidmain()
{
Trianglet1(3,4,5),t2(4,5,6);
doubles;
coutt1:;t1.disparea();
coutt2:;t2.disparea();
s=t1+t2;
cout总面积=sendl;
}
5.请在下面程序的横线处填上适当内容,以使程序完整。
#includeiostream.h
#includestring.h
classPerson
{
charname[20];
public:
Person(char*s){strcpy(name,s);}
voiddisplay(){cout”Name:”nameendl;}
};
classStudent:publicPerson
{
intgrade;
public:
Student(char*s,intg):①
{grade=g;}
voiddisplay()
{
②
;
cout”Grade:”gradeendl;
}
};
voidmain()
{
Students(“周山”,90);
s.display();
}
(1)Person(s)
(2)Person::display();
C++程序设计练习题二
一、单项选择题
1.下列各种高级语言中,不是面向对象的程序设计语言的是(D)。
A.C++B.JavaC.VBD.C
2.下列说法中正确的是(B)。
A.类定义中只能说明函数成员的函数头,不能定义函数体
B.类中的函数成员可以在类体中定义,也可以在类体之外定义
C.类中的函数成员在类体之外定义时必须要与类声明在同一文件中
D.在类体之外定义的函数成员不能操作该类的私有数据成员
3.静态数据成员的初始化必须在(B)。
A.类内B.类外C.构造函数内D.静态成员函数内
4.使用派生类的主要原因是(A)。
A.提高代码的可重用性B.提高程序的运行效率
C.加强类的封装性D.实现数据的隐藏
5.编译时的多态性通过使用(C)实现。
A.构造函数B.虚函数C.重载函数D.析构函数
6.下列关于运算符重载的描述中,正确的是(D)。
A.可以改变运算符的目数B.可以改变运算符的优先级
C.可以改变运算符的结合性D.可以改变运算符的功能
7.如有以下模板类定义:
TemplateclassT
classsum{Ta,b;
Public:
sum(Tx,Ty);}
则在类体外定义构造函数正确的是(C)。
A.templateclassT
sum::sum(Tx,Ty){a=x;b=y;}
B.templatetypenameT
sum::sum(Tx,Ty){a=x;b=y;}
C.templateclassT
sumT::sum(Tx,Ty){a=x;b=y;}
D.sumT::sum(Tx,Ty){a=x;b=y;}
8.写一个C++文件,要创建一个(B)流对象。
A.ifstreamB.ofstreamC.cinD.cout
9.下面有关重载函数的说法中正确的是(C)。
A.重载函数必须具有不同的返回值类型;B.重载函数形参个数必须不同;
C.重载函数必须有不同的形参列表;
D.重载函数名可以不同;
10.一个函数功能不太复杂但要求被频繁调用,应选用(A
)。
A.内联函数B.重载函数C.递归函数D.嵌套函数
11.关于new运算符的下列描述中,(D)是错的。
A.它可以用来动态创建对象和对象数组
B.使用它创建的对象和对象数组可以使用运算符delete删除
C.使用它创建对象时要调用构造函数
D.使用它创建对象数组时必须指定初始值
12.可以用p.a的形式访问派生类对象p的基类成员a,其中a是(D)。
A.私有继承的公有成员B.公有继承的私有成员
C.公有继承的保护成员D.公有继承的公有成员
13.若有定义“intx=17;”,则语句“coutoctx;”的输出结果是(C)。
A.11B.0x11C.21D.
14.已知f1和f2是同一类的两个成员函数,但f1不能直接调用f2,这说明(B)。
A.f1和f2都是静态函数B.f1是静态函数,f2不是静态函数
C.f1不是静态函数,f2是静态函数D.f1和f2都不是静态函数
15.假设Sample是个类,则语句“Samplea[2],*p[3];”调用构造函数的次数为(B)。
A.0B.2C.3D.5
16.C++利用(B)实现面向对象程序设计的继承性。
A.构造数据类型——类B.类的派生机制
C.构造数据类型——枚举D.函数重载与运算符重载
17.在下面有关对构造函数的描述中,正确的是(B)。
A.构造函数可以带有返回值B.构造函数的名字与类名完全相同
C.构造函数必须带有参数D.构造函数必须定义,不能缺省
18.关于成员函数特征的下述描述中,(A)是错误的。
A.成员函数一定是内联函数B.成员函数可以重载
C.成员函数可以设置参数的缺省值D.成员函数可以是静态的
19.能用友元函数重载的运算符是(.C)。
A.[]B.=C.+D.-
20.关于虚函数的描述中,(.C)是正确的。
A.虚函数是一个static类型的成员函数
B.虚函数是一个非成员函数
C.基类中说明了虚函数后,派生类中将其对应的函数可不必说明为虚函数
D.派生类的虚函数与基类的虚函数具有不同的参数个数和类型
21.下列语句中不存在类型转换的是(.C)。
A.int(1.1);B.(double)2.2;C.inti=1;D.charc=97;
22.定义类模板时要使用关键字(D)。
A.constB.newC.deleteD.template
23.下列不是文件流类的是(B)。
A.ifstreamB.iostreamC.fstreamD.ofstream
24.下面对静态数据成员的描述中,正确的是(D)。
A.静态数据成员可以在类体内进行初始化
B.静态数据成员不可以被类的对象调用
C.静态数据成员不受private控制符的限制
D.静态数据成员可以直接用类名调用
25.在公有派生情况下,有关派生类对象和基类对象的关系,下列叙述不正确的是(C)。
A.派生类的对象可以赋给基类的对象
B.派生类的对象可以初始化基类的引用
C.指向派生类对象的基类指针可以直接访问派生类中的成员
D.派生类的对象的地址可以赋给指向基类的指针
26.以下基类中的成员函数中表示纯虚函数的是(B)。
A.virtualvoidvf(int);B.virtualvoidvf(int)=0;
C.virtualvoidvf(int=0);D.virtualvoidvf(int){};
27.下面关于运算符重载的描述错误的是(C)。
A.重载不能改变操作数的个数、运算符的优先级、运算符的结合性和运算符的语法结构
B.不是所有的运算符都可以进行重载
C.运算符函数的调用必须使用关键字operator
D.在C++语言中不可通过运算符重载创造出新的运算符
28.设有函数模板
templateclassQ
QSum(Qx,Qy){return(x)+(y);}
则下列语句中对该函数模板错误的使用是(D)。
A.Sum(10,2);B.Sum(5.0,6.7);
C.Sum(15.2f,16.0f);D.Sum(″AB″,″CD″);
29.如果编程者没有显式定义构造函数(包括复制构造函数),C++编译器就(D)。
A.出现编译错误B.没有构造函数C.必须显示定义D.隐式定义缺省的构造函数
30.假设已经有定义char*constname=chen;下面的语句中正确的是(A)。
A.name[3]=q;B.name=lin;
C.name=newchar[5];D.name=newchar(q);
31.实现以读方式打开文件“D:\File.txt”,以下不能实现目的的语句是(.C)。
A.ifstreaminf(D:\\Filetxt,ios::in);
B.ifstreaminf(D:\\File.txt);
C.istreaminf(D:\\File.txt,ios::out);
D.fstreaminf(D:\\File.txt,ios::in
ios::out);
32.下列不是描述类的成员函数的是(.C)
A.构造函数B.析构函数C.友元函数D.拷贝构造函数
33.所谓多态性是指(B)
A.不同的对象调用不同名称的函数B.不同的对象调用相同名称的函数
C.一个对象调用不同名称的函数D.一个对象调用不同名称的对象
34.类Point的拷贝构造函数是(C)
A.Point()B.Point(Point*)C.Point(Point)D.Point(Point)
35.下面关于静态成员的描述中,正确的是(A)
A.静态数据成员是类的所有对象共享的数据
B.类的每个对象都有自己的静态数据成员
C.类的不同对象有不同的静态数据成员值
D.静态数据成员不能通过类的对象访问
36.在下面有关友元函数的描述中,正确的说法是(A)。
A.友元函数是独立于当前类的外部函数B.一个函数不能同时定义为两个类的友元函数
C.友元函数必须在类的外部定义D.在外部定义友元函数时,必须加关键字friend
37.下面对类的析构函数的定义是(D)。
A.X::~X(参数);B.voidX::~X(参数);C.voidX::~X();D.X::~X();
38.假定一个类的构造函数为“A(intaa=1,intbb=0){a=aa;b=bb;}”,则执行“Ax(4);”语句后,x.a和x.b的值分别为(.C)。
A.1和0B.1和4C.4和0D.4和1
二、判断题
1.C++中,对象保存在内存中,栈内存是自动分配和释放的,而堆内存需要用户自己申请和释放。(√)
1.C++不允许定义有默认参数的函数。(×)
2.构造函数和析构函数都不能重载。(×)
3.构造函数和析构函数都不可以由程序员调用,只能由系统自动调用。(√)
2.凡是用inline说明的函数一定是内联函数。(√
4.)
3.友元函数是独立于当前类的外部函数。(×
5.)
4.静态成员函数与在一般的成员函数一样,都隐含有一个this指针。√
6.
5.()常量和引用在声明时必须初始化。(×
7.)
6.无论何时编译器都为类构造一个无参数的缺省的构造函数。(√
8.)
9.拷贝构造函数使用本类对象的指针作为参数初始化新创建的对象。(×)
10.构造函数和析构函数都与类同名。(×)
11.不能在类声明中给数据成员赋初值。(×)
12.成员函数体写在类外部的一定不是内联函数,写在类内部的一定是内联函数。(√)
13.构造函数和析构函数都可以是虚函数。(×)
14.构造函数是不能说明它的返回值类型的,但可以说明为void类型。(×)
15.运算符=、()、[]、-不能用友元方式重载。(×)
16.虚基类中的成员函数都是虚函数。(×)
17.如果一个类至少有一个虚函数,那么该类就被称为抽象类。(×)
三、简答题
1.什么是面向对象程序设计?面向对象程序设计是一种新型的程序设计范型。这种范型的主要特征是:程序=对象+消息。面向对象程序设计具有封装性、继承性和多态性。
2.什么是继承性?请举例说明。继承所表达的是对象类之间的相关关系,这种关系使得某类对象可以继承另外一类对象的特征和能力。现实生活中,继承是很普遍和容易理解的。例如我们继承了父辈的一些特征,如种族、血型、眼睛的颜色等,父母是我们所具有的属性的基础。
3.结构struct和类class有什么异同?类与结构的相同点:
(1)都是用户自定义的数据类型;
(2)都可以有数据成员和函数成员,且成员可以有访问控制。
(3)对成员的访问形式是一样的,都是通过’·’操作符进行访问的。
类与结构的不同点:
(1)结构的成员访问方式默认是public的,而类的成员访问方式默认是private的;
(2)使用的场合有所区别:结构通常被用在比较简单的场合,即没有函数成员,只有数据成员的场合。类的使用比较普及,它可以更好的体现面向对象的思想。
4.在定义拷贝构造函数时,为什么通常还要定义一个重载的赋值运算符?拷贝构造函数是用一个对象初始化另一个对象时调用,定义了拷贝构造函数通常涉及到对象内有指针成员,需要定义拷贝构造函数复制指针所指向的内存单元。对象赋值也有同样的问题,如果要将对象指针所指向的内存单元也赋给另一个对象,就必须重载赋值运算符。
什么是面向对象程序设计?面向对象程序设计是一种新型的程序设计范型。这种范型的主要特征是:程序=对象+消息。面向对象程序设计具有封装性、继承性和多态性。
5.
什么是继承性?请举例说明。继承所表达的是对象类之间的相关关系,这种关系使得某类对象可以继承另外一类对象的特征和能力。现实生活中,继承是很普遍和容易理解的。例如我们继承了父辈的一些特征,如种族、血型、眼睛的颜色等,父母是我们所具有的属性的基础。
6.
结构struct和类class有什么异同?类与结构的相同点:
(1)都是用户自定义的数据类型;
(2)都可以有数据成员和函数成员,且成员可以有访问控制。
(3)对成员的访问形式是一样的,都是通过’·’操作符进行访问的。
类与结构的不同点:
(1)结构的成员访问方式默认是public的,而类的成员访问方式默认是private的;
(2)使用的场合有所区别:结构通常被用在比较简单的场合,即没有函数成员,只有数据成员的场合。类的使用比较普及,它可以更好的体现面向对象的思想。
(3)类支持继承的机制,而结构则不能被继承。
7.
虚析构函数有什么作用?对象销毁时,需要调用析构函数。在多态调用时,是用基类的指针访问派生类的对象。如果析构函数是非虚函数,则基类指针只能访问基类的析构函数,而不能访问派生类的析构函数,导致派生类对象销毁时,没有调用派生类的析构函数,只是调用了基类的析构函数。如果把析构函数定义成虚函数,则可克服这个问题。
8.
什么是类?什么是对象?对象与类的关系是什么?(1)类是一组具有共同的属性特征和行为特征的对象的抽象;
(2)对象就是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位,由一组属性和一组行为构成。
(3)类和对象之间的关系是抽象和具体的关系,类是对多个对象进行抽象的结果,对象是类的具体实现。
9.
结构struct和类class有什么异同?类与结构的相同点:
(1)都是用户自定义的数据类型;
(2)都可以有数据成员和函数成员,且成员可以有访问控制。
(3)对成员的访问形式是一样的,都是通过’·’操作符进行访问的。
类与结构的不同点:
(1)结构的成员访问方式默认是public的,而类的成员访问方式默认是private的;
(2)使用的场合有所区别:结构通常被用在比较简单的场合,即没有函数成员,只有数据成员的场合。类的使用比较普及,它可以更好的体现面向对象的思想。
10.
四、程序分析题
1.指出下列程序中的1处错误,并说明为什么。
#includeiostream.h
classStudent{
charname[10];
intage;
floataver;
voidprintStu();
};
voidmain()
{
Studentp1,p2,p3;
p1.age=30;
//…
}
错误位置:p1.age=30;
错误原因:类的对象不能访问类的私有数据成员
2.指出下列程序中的2处错误,并说明为什么。
#includeiostream.h
classTest{
public:
Test(inty=10){data=y;}
intgetData()const{return++data;}
staticintgetCount()
{
coutDataisdataendl;
returncount;
}
private:
intdata;
staticintcount;
};
错误1位置:intgetData()const{return++data;}
错误1原因:用const约束的函数是不允许改变数据成员的值的
错误2位置:coutDataisdataendl;
错误2原因:此语句是在静态函数getCount()中的,而静态函数不允许访问非静态成员data
3.写出下列程序的运行结果。
#includeiostream.h
classtest
{
private:
intnum;
floatfl;
public:
test();
intgetint(){returnnum;}
floatgetfloat(){returnfl;}
~test();
};
test::test()
{
coutInitalizingdefaultendl;
num=0;fl=0.0;
}
test::~test()
{
coutDestructorisactiveendl;
}
voidmain()
{
testarray[2];
coutarray[1].getint()array[1].getfloat()endl;
}
程序输出结果为:
Initalizingdefault
Initalizingdefault
00
Destructorisactive
Destructorisactive
4.写出下面程序的运行结果
#includeiostream.h
classA
{
inta;
public:
A(intaa=0){a=aa;couta=aendl;}
};
classB
{
intb;
public:
B(intbb=0){b=bb;coutb=bendl;}
};
classC:publicB
{
Aa;
public:
C(){cout”Cdefaultconstructor”endl;}
C(inti,intj):a(i),B(j){cout”Cconstructor”endl;}
};
voidmain()
{
Cc1,c2(5,6);
}
程序输出结果为:
b=0
a=0
Cdefaultconstructor
b=6
a=5
Cconstructor
5.指出下列程序中的1处错误,并说明为什么。
#includeiostream.h
classStack{
public:
Stack(intsz);
private:
char*p;
intsize;
};
Stack::Stack(intsz)
{
p=newchar[size=sz];
}
voidmain()
{
Stackstt;
//…
}
错误位置:Stackstt;
错误原因:程序中没有定义无参或默认参数的构造函数
6.指出下列程序中的1处错误,并说明为什么。
#includeiostream.h
classshape{
public:
intarea(){return0;}
};
classrectangle:publicshape{
public:
inta,b;
voidsetLength(intx,inty){a=x;b=y;}
intarea(){returna*b;}
};
voidmain(){
rectangler;
r.setLength(3,5);
shape*s=r;
coutr.area()endl;
couts.area()endl;
}
错误位置:couts.area()endl;
错误原因:s是指向对象的指针,而通过指针访问类成员时要使用成员访问运算符-
7.写出下面程序的输出结果。
#includeiostream.h
classMyClass{
public:
intnumber;
voidset(inti);
};
intnumber=3;
voidMyClass::set(inti){number=i;}
voidmain()
{
MyClassmy1;
intnumber=10;
my1.set(5);
coutmy1.numberendl;
my1.set(number);
coutmy1.numberendl;
my1.set(::number);
coutmy1.number;
}
5
10
3
8.写出下面程序的运行结果
#includeiostream.h
classSample
{
intx,y;
public:
Sample(){x=y=0;}
Sample(inti,intj){x=i;y=j;}
voidcopy(Samples);
voidsetxy(inti,intj){x=i;y=j;}
voidprint(){coutx=x,y=yendl;}
};
voidSample::copy(Samples)
{x=s.x;y=s.y;}
voidfunc(Samples1,Samples2)
{
s1.setxy(10,20);
s2.setxy(30,40);
}
voidmain()
{
Samplep(1,2),q;
q.copy(p);
func(p,q);
p.print();
q.print();
}
x=1,y=2
x=30,y=40
9.写出下面程序的输出结果。
#includeiostream.h
classA
{
private:
staticintn;
intX;
public:
A(intx=0){X=x;n++;}
~A(){n--;}
staticintGetNum(){returnn;}
voidprint();
};
voidA::print(){coutn=n,X=Xendl;}
intA::n=0;
voidmain()
{
A*p=newA(12);
p-print();
Aa(34);
a.print();
deletep;
coutn=A::GetNum()endl;
}
n=1,X=12
n=2,X=34
n=1
10.写出下面程序的运行结果。
#includeiostream.h
classA
{
public:
intn;
};
classB:virtualpublicA{};
classC:virtualpublicA{};
classD:publicB,publicC
{
intgetn(){returnB::n;}
};
voidmain()
{
Dd;
d.B::n=10;
d.C::n=20;
coutd.B::n,d.C::nendl;
}
20,20
五、完成程序题
1.下面程序中A是抽象类,为使其输出是:
ThisisclassBprinting.
ThisisclassCprinting.
请在横线处填写适当内容,以使程序完整。
#includeiostream.h
classA{
public:
①________;
};
classB:publicA{
public:
voidprintMe(){coutThisisclassBprinting.endl;}
};
classC:publicB{
voidprintMe(){coutThisisclassCprinting.endl;}
};
voidprint(②________)
{
a.printMe();
}
voidmain()
{
Bb;
Cc;
print(b);print(c);
}
#includeiostream.h
#includemath.h
classComplex
{
intreal,image;
public:
Complex(){};
Complex(inti,intj=0){real=i;image=j;}
friendostreamoperator(ostreamos,Complexc)
{coutc.real(c.image0?+:-)abs(c.image)iendl;
returnos;}
Complexoperator+(Complexc){
returnComplex(real+c.real,image+c.image);}
};
voidmain()
{
Complexc1(1,2),c2(3,-4),c3;
c3=c1+c2;
coutc3;
}
3.
3.设计一个复数类Complex,包含实部real和虚部image两个私有数据成员,另有一个重载运算符“+”(用成员函数实现),以实现求两个复数对象之和,和一个重载运算符“”,以实现输出复数类的对象。在主程序中用实例进行测试。
1.请在下面程序的横线处填上适当内容,以使类定义完整。
classbase{
protected:
inta;
public:
base(){a=0;}
base(inti){a=i;}
base(baseb){a=b.a;}
};
classderived:publicbase{
private:
intd;
public:
derived(){d=0;}
derived(inti,intj):①_____{d=j;}
derived(derivedb):②________{d=b.d;}
};
(1)base(i)
(2)base(b)
4.编写一个对具有n个元素的数组x[]求最大值的程序,要求将求最大值的函数设计成函数模板。#includeiostream.h
templateclassT
Tmax(Tx[],intn)
{
inti;
Tmaxv=x[0];
for(i=1;in;i++)
if(maxvx)
maxv=x;
returnmaxv;
}
voidmain()
{
inta[]={4,5,2,8,9,3};
doubleb[]={3.5,6.7,2,5.2,9.2};
couta数组最大值:max(a,6)endl;
coutb数组最大值:max(b,5)endl;
}
3.
n=1,X=12
n=2,X=34
n=1
4.
20,20
5.编写一个程序,设计一个圆类circle和一个桌子类table,另设计一个圆桌类roundtable,它是从前两个类派生的,要求输出一个圆桌的高度、面积和颜色等数据。
提示:
circle类包含私有数据成员radius和求圆面积的成员函数getarea();
table类包含私有数据成员height和返回高度的成员函数getheight()。
roundtable类继承所有上述类的数据成员和成员函数,添加私有数据成员color和相应的成员函数。
#includeiostream.h
#includestring.h
classcircle
{
doubleradius;
public:
circle(doubler){radius=r;}
doublegetarea(){returnradius*radius*3.14;}
};
classtable
{
doubleheight;
public:
table(doubleh){height=h;}
doublegetheight(){returnheight;}
};
classroundtable:publictable,publiccircle
{
char*color;
public:
roundtable(doubleh,doubler,charc[]):circle(r),table(h)
{
color=newchar[strlen(c)+1];
strcpy(color,c);
}
char*getcolor(){returncolor;}
};
voidmain()
{
roundtablert(0.8,1.2,黑色);
cout圆桌属性:endl;
cout高度:rt.getheight()米endl;
cout面积:rt.getarea()平方米endl;
cout颜色:rt.getcolor()endl;
}