面向对象程序设计复习题.docx
《面向对象程序设计复习题.docx》由会员分享,可在线阅读,更多相关《面向对象程序设计复习题.docx(21页珍藏版)》请在冰豆网上搜索。
面向对象程序设计复习题
《面向对象程序设计》复习题
一、单项选择题
1.(A)是面向对象系统包含的要素。
A、类B、多态C、友元D、重载
2.下列对常量的定义中,错误的是( C )。
A、MyClassconstobj(3,4);B、char*constp="hello";
C、int&ref=2; D、voidshow()const;
3.若有如下函数声明:
voidFun(intx);,则下列(D )能与该函数形成重载。
A、voidFun(inty);B、voidFun(intx,inty='1');
C、intFun(intx);D、voidFun(int)const;
4.下列对构造函数和析构函数的描述中,错误的是( B )。
A、构造函数可以重载
B、析构函数名与类名相同
C、构造函数中可以设置参数的缺省值
D、类中只有一个析构函数
5.下列对友元的描述中,错误的是( C )。
A、友元破坏了类的封装性
B、友元提高了程序的运行效率
C、友元可以在类外声明和定义
D、友元能够访问类中的私有成员
6.下列对继承的描述中,正确的是( A )。
A、公有派生类对象能够访问基类的公有成员
B、派生类只继承了基类的公有成员和保护成员
C、派生类对象不能访问基类的保护成员
D、派生类不改变基类成员的访问权限
7.程序中,编译时出错的语句是(D )。
classBase{};
classDerived:
publicBase{};
DerivedobjD1;
BaseobjB=objD1;//A
Base*pb=&objD1;//B
Base&refB=objD1;//C
DerivedobjD2=objB;//D
8.下面对派生类的描述中,正确的是( B )。
A、派生类是对基类的抽象
B、一个派生类可以作为另一个派生类的基类
C、派生类只能有一个直接基类
D、派生类的缺省继承方式是public
9.实现动态联编必须通过(A )调用虚函数。
A、基类引用B、类名C、对象名D、构造函数
10.C++流中重载的运算符>>,是一个(B)。
A、用于输出操作的非成员函数B、用于输入操作的非成员函数
C、用于输出操作的成员函数D、用于输入操作的成员函数
11.(A)不是基于对象系统包含的要素。
A、多态B、对象C、类D、继承
12.下列对常量的定义中,错误的是( C )。
A、intconstsize=10;B、char*constp="GoodLuck";
C、voidconstprint(); D、constMyClassobj(10,10);
13.设Address表示整型变量x的地址,则下列语句执行后的输出结果为(D )。
intx=100,&r=x;
cout<A、Address-100B、100-Address
C、Address-AddressD、100-100
14.若函数原型为voidFun(intx=9,inty=8,charz='7'),则下列调用错误的是(B)。
A、Fun()B、Fun(“hello”)
C、Fun(1,2)D、Fun(2,4,'a')
15.若有如下函数声明:
voidFun(intx);,则下列( C )不能与该函数形成重载。
A、voidFun(intx,inty);B、voidFun(doublex);
C、voidFun(intx,inty=1);D、voidFun(intx)const;
16.下列对构造函数和析构函数的描述中,正确的是(A )。
A、析构函数不可以重载
B、构造函数不能定义为内联函数
C、构造函数中不能设置参数的缺省值
D、析构函数名与类名相同
17.下面对静态成员的描述中,错误的是( C )。
A、静态数据成员的提出是为了解决数据共享问题
B、静态数据成员的初始化在类体外进行
C、类的不同对象有不同的静态数据成员值
D、静态成员函数可以直接访问类中的静态数据成员
18.下列对友元的描述中,正确的是( D )。
A、友元可以在类外声明和定义
B、友元降低了程序的运行效率
C、友元不能访问类中的保护成员
D、友元破坏了类的封装性
19.下列对继承的描述中,错误的是( C )。
A、派生类对象不能访问基类的保护成员
B、派生类对基类成员的访问权限随着继承方式而改变
C、派生类成员可以访问基类的私有成员
D、派生类继承了基类的所有数据成员
20.程序中,编译时出错的语句是(D )。
classBase{};
classDerived:
publicBase{};
DerivedobjD1;
BaseobjB=objD1;//A
Base*pb=&objD1;//B
Base&refB=objD1;//C
DerivedobjD2=objB;//D
21.下面对派生类的描述中,错误的是( D )。
A、派生类是对基类的具体化
B、派生类能够作为基类继续派生新类
C、派生类可以有多个直接基类
D、派生类的缺省继承方式是private
22.实现动态联编不能通过(A )调用虚函数。
A、构造函数B、基类引用C、基类指针D、基类指针或引用
23.下面( D )不是抽象类的特性。
A、可以说明纯虚函数
B、不能说明抽象类的对象
C、用做基类,提供公共的接口
D、可以定义虚构造函数
24.C++流中重载的运算符<<,是一个(B)。
A、用于输出操作的成员函数B、用于输出操作的非成员函数
C、用于输入操作的成员函数D、用于输入操作的非成员函数
25:
下列有关类的说法不正确的是()。
A. 对象是类的一个实例
B. 任何一个对象只能属于一个具体的类
C. 一个类只能有一个对象
D.类与对象的关系和数据类型与变量的关系相似
答案:
C
分析:
对象是类的一个实例,类与对象的关系和数据与变量的关系相似,所以一个类可以有多个对象。
26:
下面()项是对构造函数和析构函数的正确定义。
A.voidX:
:
X(),voidX:
:
~X()
B.X:
:
X(参数),X:
:
~X()
C.X:
:
X(参数),X:
:
~X(参数)
D.voidX:
:
X(参数),voidX:
:
~X(参数)
答案:
B
分析构造函数无返回类型、可带参数、可重载;析构函数无返回类型、不可带参数、不可重载。
27:
()的功能是对对象进行初始化。
A.析构函数B.数据成员C.构造函数D.静态成员函数
答案:
C
分析:
当一个对象定义时,C++编译系统自动调用构造函数建立该对象并进行初始化;当一个对象的生命周期结束时,C++编译系统自动调用析构函数注销该对象并进行善后工作;
28:
下列表达方式正确的是()。
A.classP{B.classP{
public:
public:
intx=15;intx;
voidshow(){cout<};}
C.classP{D.classP{
intf;public:
};inta;
f=25;voidSeta(intx){a=x;}};
答案:
D
分析:
在类体内不可对数据成员进行初始化;类定义结束时需用分号;只有类中的成员函数才能存取类中的私有数据。
29:
拷贝构造函数具有的下列特点中,()是错误的。
A. 如果一个类中没有定义拷贝构造函数时,系统将自动生成一个默认的
B. 拷贝构造函数至少有一个参数,并且是该类对象的引用
C. 拷贝构造函数是一种成员函数
D.拷贝构造函数的名字不能用类名
答案:
D
分析:
如果一个类中没有定义拷贝构造函数时,系统将自动生成一个默认的;拷贝构造函数至少有一个参数,并且是该类对象的引用;拷贝构造函数的名字与类同名,并且不被指定返回类型;拷贝构造函数是一种成员函数。
30:
关于静态成员的描述中,()是错误的。
A. 静态成员可分为静态数据成员和静态成员函数
B. 静态数据成员定义后必须在类体内进行初始化
C. 静态数据成员初始化不能在构造函数中完成
D. 静态成员函数中不能直接引用非静态成员
答案:
B
分析:
静态成员可分为静态数据成员和静态成员函数;静态数据成员被定义后,必须对它进行初始化,初始化在类体外进行,一般放在该类的实现部分最合适,也可以放在其他位置,例如,放在主函数前面等;静态数据成员初始化与该类的构造函数和析构函数无关;在静态成员函数的实现中,可以直接引用静态成员,但不能直接引用非静态成员。
31:
关于友元的描述中,()是错误的。
A. 友元函数是成员函数,它被说明在类体内
B. 友元函数可直接访问类中的私有成员
C. 友元函数破坏封装性,使用时尽量少用
D. 友元类中的所有成员函数都是友元函数
答案:
A
分析:
友元函数是非成员函数,在类体内说明了,在类体外定义,定义和调用等同于一般的普通函数;由于它可以直接访问类的私有成员,因此破坏了类的封装性和隐藏性,尽量少用。
二、填空题
1.下列运算符既可以作为类的成员函数重载,也可以作为类的友元函数重载,请在表格中的空白处填上正确的表达式。
表达式
成员函数
友元函数
a+b
(1)
(2)
a++
(3)
operator++(a)
-a
a.operator-()
(4)
1.答案:
(1)a.operator+(b)
(2)operator+(a,b)
(3)a.operator++()(4)operator–(a)
2.下列程序执行后的输出结果是12,21,22,请将下列程序补充完整。
#include
voidfun1(
(1) ,intb){intc;c=a;a=b;b=c;}
voidfun2(
(2) ,int*b){intc;c=*a; (3) ;*b=c;}
voidfun3( (4) ,intb){intc;c=a; (5) ;b=c;}
voidmain(){
intx,y;
x=1;y=2;fun1(x,y);cout<x=1;y=2;fun2(&x,&y);cout<x=1;y=2;fun3(x,y);cout<}
2.答案:
(1)inta
(2)int*a(3)*a=*b
(4)int&a(5)a=b
3.下列程序执行后的输出结果是B0D00B1D23~D~B~D~B,请将下列程序补充完整。
classBase{
public:
Base(inti=0){x=i;cout<<'B'<~Base(){cout<<"~B"<private:
intx;
};
classDerived:
publicBase{
inty,z;
public:
__________________
(1)________________________//Constructor
__________________
(2)________________________//Destructor
};
voidmain(){
Derivedobj1;
Derivedobj2(1,2,3);
}
答案:
(1)Derived(inta=0,intb=0,intc=0):
Base(a){y=b;z=c;cout<<'D'<(2)~Derived(){cout<<"~D";}
4:
设有如下程序结构:
classBox
{…};
voidmain()
{BoxA,B,C;}
该程序运行时调用
(1)次构造函数;调用
(2)次析构函数。
答案:
(1)3
(2)3
分析:
每创建一个对象自动调用一次构造函数,在这里创建了A、B、C三个对象,所以共调用了三次构造函数;每释放一个对象,系统自动调用一次析构函数,A、B、C对象释放时,分别调用析构函数,所以析构函数共调用了三次。
5:
设A为test类的对象且赋有初值,则语句testB(A);表示。
答案:
用对象A初始化对象B。
分析:
执行testB(A);语句相当于调用了默认拷贝构造函数,用对象A初始化对象B。
6:
在类外,利用“对象名.成员名”的形式访问的对象成员仅限于被声明为
(1)的成员;若要访问其他成员变量,需要通过
(2)函数或(3)函数。
答案:
(1)public
(2)成员(3)友元
分析:
类体内的数据成员可声明为公有的、私有的和保护的,公有的数据成员可利用“对象名.成员名”形式来进行访问;私有的数据成员能被类中的成员函数或友元函数所调用;保护的数据成员可以在类体中使用,也可以在派生类中使用,但不能在其他类外通过对象使用。
三、写程序结果题
1.#include
classTest{
public:
Test(doublem,doublen,doubled):
p(d){x=m;y=n;}
voidShow();
voidShow()const;
private:
doublex,y;
constdoublep;
};
voidTest:
:
Show(){
cout<cout<<"p="<
}
voidTest:
:
Show()const{
cout<cout<<"p="<
}
voidmain(){
Testa(8.9,2.5,3.1416);
a.Show();
constTestb(2.5,8.9,3.14);
b.Show();
}
答案:
8.92.5
p=3.1416
2.58.9const
p=3.14const
2.#include
classA{
public:
A(inti){cout<<"Constructor"<A(A&r){cout<<"Copyconstructor"<~A(){cout<<"Destructor"<A&operator=(A&r);
voidoutput(){cout<<*p<private:
int*p;
};
A&A:
:
operator=(A&r){
cout<<"Assignment"<if(this==&r)return*this;
deletep;
p=newint(r.p);
return*this;
};
voidmain(){
Aa(5);
Ab=a;
Ac(6);
c=a;
c.output();
};
答案:
Constructor
Copyconstructor
Constructor
Assignment
5
Destructor
Destructor
Destructor
3.#include
classBase1{
public:
Base1(intx){cout<<"Base1'scon."<~Base1(){cout<<"Base1'sdes."<};
classBase2{
public:
Base2(intx){cout<<"Base2'scon."<~Base2(){cout<<"Base2'sdes."<};
classDerived:
publicBase2,publicBase1{
public:
Derived(intx,inty):
Base1(y),Base2(x){cout<<"Derived'scon."<~Derived(){cout<<"Derived'sdes."<};
voidmain(){
Derivedobj(1,2);
}
答案:
Base2'scon.1
Base1'scon.2
Derived'scon.
Derived'sdes.
Base1'sdes.
Base2'sdes.
4.#include
classA{
inta,b;
public:
A(){
a=b=0;
cout<<"DefaultConstructingObject"<<''<}
A(intaa,intbb){
a=aa;b=bb;
cout<<"ConstructingObject"<<''<}
~A(){cout<<"DestructingObject"<<''<};
voidmain()
{
Ax,y(2,3),z(4,5);
}
答案:
DefaultConstructingObject00
ConstructingObject23
ConstructingObject45
DestructingObject45
DestructingObject23
DestructingObject00
5.#include
template
classFF{
TTa1,a2,a3;
public:
FF(TTb1,TTb2,TTb3){
a1=b1;a2=b2;a3=b3;
}
TTSum(){returna1+a2+a3;}
};
voidmain()
{
FFx(2,3,4),y(5,7,9);
cout<}
答案:
921
6:
分析找出以下程序中的错误,说明错误原因,给出修改方案使之能正确运行。
#include
classone
{
inta1,a2;
public:
one(intx1=0,x2=0);
};
voidmain()
{
onedata(2,3);
cout<cout<}
分析:
出错原因:
构造函数参数表语法错;构造函数没有函数体;类的对象不能直接访问类的私有成员。
改正后的程序如下:
#include
classone
{inta1,a2;
public:
one(intx1=0,intx2=0){a1=x1;a2=x2;}
intgeta1(){returna1;}
intgeta2(){returna2;}
};
voidmain()
{onedata(2,3);
cout<cout<}
7:
分析以下程序的错误原因,给出修改方案使之能正确运行。
#include
classAmplifier{
floatinvol,outvol;
public:
Amplifier(floatvin,floatvout)
{invol=vin;outvol=vout;}
floatgain();
};
Amplifier:
:
floatgain(){returnoutvol/invol;}
voidmain()
{Amplifieramp(5.0,10.0);
cout<<"\n\nThegainis=>"<}
分析:
成员函数在类体外定义格式是:
函数返回类型类名:
:
成员函数名(参数表);成员函数调用格式是:
对象名.成员函数名(参数表)。
改正后的程序如下:
#include
classAmplifier
{floatinvol,outvol;
public:
Amplifier(floatvin,floatvout){invol=vin;outvol=vout;}
floatgain();
};
floatAmplifier:
:
gain(){returnoutvol/invol;}
voidmain()
{Amplifieramp(5.0,10.0);
cout<<"\n\nThegainis=>"<}
8:
下列程序的运行结果是。
#include
classpoint
{intx,y;
public:
point(inta,intb)
{x=a;y=b;
cout<<"callingtheconstructorfunction."<}
point(point&p);
friendpointmove(pointq);
~point(){cout<<"callingthedestructorfunction.\n";}
intget