};}
C.classP{D.classP{
intf;public:
};inta;
f=25;voidSeta(intx){a=x;}
答案:
D
分析:
在类体内不可对数据成员进行初始化;类定义结束时需用分号;只有类中的成员函数才能存取类中的私有数据。
5、对类的构造函数和析构函数描述正确的是()。
A. 构造函数可以重载,析构函数不能重载
B.构造函数不能重载,析构函数可以重载
C.构造函数可以重载,析构函数也可以重载
D.构造函数不能重载,析构函数也不能重载
答案:
A
6、类的析构函数的作用是()。
A.一般成员函数B.类的初始化C.对象初始化D.删除对象
答案:
D
7、对于结构中定义的成员,其默认的访问权限为()。
A.publicB.protectedC.privateD.static
答案:
C
8、为了使类中的某个成员不能被类的对象通过成员操作符访问,则不能把该成员的访问权限定义为()。
A.publicB.protectedC.privateD.static
答案:
a
9、下列有关类的说法不正确的是。
A.类是一种用户自定义的数据类型
B.只有类中的成员函数或类的友元函数才能存取类中的私有数据
C.在类中(用class定义),如果不作特别说明,所有的数据均为私有数据
D.在类中(用class定义),如果不作特别说明,所有的成员函数均为公有数据
答案:
d
(3)以下有关析构函数的叙述不正确的是()
A.在一个类只能定义一个析构函数B.析构函数和构造函数一样可以有形参
C.析构函数不允许用返回值D.析构函数名前必须冠有符号“~”
答案:
b
10、以下有关类与结构体的叙述不正确的是()
A.结构体中只包含数据;类中封装了数据和操作
B.结构体的成员对外界通常是开放的;类的成员可以被隐藏
C.用struct不能声明一个类型名;而class可以声明一个类名
D.结构体成员默认为public;类成员默认为private
答案:
C
11、以下叙述中不正确的是()
A.一个类的所有对象都有各自的数据成员,它们共享函数成员
B.一个类中可以有多个同名的成员函数
C.一个类中可以有多个构造函数、多个析构函数
D.在一个类中可以声明另一个类的对象作为它的数据成员
答案:
C
12、以下不属于构造函数特征的是()
A.构造函数名与类名相同B.构造函数可以重载
C.构造函数可以设置默认参数D.构造函数必须指定函数类型
答案:
d
13、以下有关类和对象的叙述不正确的是()
A.任何一个对象都归属于一个具体的类
B.类与对象的关系和数据类型与变量的关系相似
C.类的数据成员不允许是另一个类的对象
D.一个类可以被实例化成多个对象
答案:
C
14、设有定义:
classperson
{intnum;
charname[10];
public:
voidinit(intn,char*m);
...
};
personstd[30];
则以下叙述不正确的是()
A.std是一个含有30个元素的对象数组
B.std数组中的每一个元素都是person类的对象
C.std数组中的每一个元素都有自己的私有变量num和name
D.std数组中的每一个元素都有各自的成员函数init
答案:
d
15、设有以下类的定义:
classEx
{intx;
public:
voidsetx(intt=0);
};
若在类外定义成员函数setx(),以下定义形式中正确的是()
A.voidsetx(intt){...}
B.voidEx:
:
setx(intt=0){...}
C.Ex:
:
voidsetx(intt=0){...}
D.voidEx:
:
setx(){...}
答案:
b
16、
假设OneClass为一个类,则该类的拷贝初始化构造函数的声明语句为()。
A.OneClass(OneClassp);B.OneClass&(OneClassp);
C.OneClass(OneClass&p);D.OneClass(OneClass*p);
答案:
C
17、下面对于友元函数描述正确的是()。
A.友元函数的实现必须在类的内部定义
B.友元函数是类的成员
C.友元函数破坏了类的封装性和隐藏性
D.友元函数不能访问类的私有成员
答案:
C
18、关于友元的描述中,()是错误的。
A. 友元函数是成员函数,它被说明在类体内
B. 友元函数可直接访问类中的私有成员
C. 友元函数破坏封装性,使用时尽量少用
D. 友元类中的所有成员函数都是友元函数
答案:
A
分析:
友元函数是非成员函数,在类体内说明了,在类体外定义,定义和调用等同于一般的普通函数;由于它可以直接访问类的私有成员,因此破坏了类的封装性和隐藏性,尽量少用。
19、拷贝构造函数具有的下列特点中,()是错误的。
A. 如果一个类中没有定义拷贝构造函数时,系统将自动生成一个默认的
B. 拷贝构造函数只有一个参数,并且是该类对象的引用
C.拷贝构造函数是一种成员函数
D.拷贝构造函数的名字不能用类名
答案:
D
分析:
如果一个类中没有定义拷贝构造函数时,系统将自动生成一个默认的;拷贝构造函数只有一个参数,并且是该类对象的引用;拷贝构造函数的名字与类同名,并且不被指定返回类型;拷贝构造函数是一种成员函数。
20、下面对静态数据成员的描述中,正确的是()。
A.静态数据成员可以在类体内进行初始化
B.静态数据成员不可以在类体内进行初始化
C.静态数据成员不能受private控制符的作用
D.静态数据成员可以直接用类名调用
答案:
C
21、下面对静态数据成员的描述中,正确的是()。
A.静态数据成员是类的所有对象共享的数据
B.类的每一个对象都有自己的静态数据成员
C.类的不同对象有不同的静态数据成员值
D.静态数据成员不能通过类的对象调用
答案:
A
22、关于静态成员的描述中,()是错误的。
A. 静态成员可分为静态数据成员和静态成员函数
B. 静态数据成员定义后必须在类体内进行初始化
C. 静态数据成员初始化不使用其构造函数
D. 静态数据成员函数中不能直接引用非静态成员
答案:
B
分析:
静态成员可分为静态数据成员和静态成员函数;静态数据成员被定义后,必须对它进行初始化,初始化在类体外进行,一般放在该类的实现部分最合适,也可以放在其他位置,例如,放在主函数前面等;静态数据成员初始化与该类的构造函数和析构函数无关;在静态成员函数的实现中,可以直接引用静态成员,但不能直接引用非静态成员。
24、以下关于静态成员变量的叙述不正确的是()
A.静态成员变量为类的所有对象所公有
B.静态成员变量可以在类内任何位置上声明
C.静态成员变量的赋初值必须放在类外
D.定义静态成员变量时必须赋初值
25、定义静态成员函数的主要目的是()
A.方便调用B.有利于数据隐藏
C.处理类的静态成员变量D.便于继承
26、以下叙述不正确的是()
使用静态数据成员:
A.可以节省内存空间B.是为了解决数据共享问题
C.可以直接用类名来引用D.可以提高序运算速度
二、填空题
1、设有如下程序结构:
classBox
{…};
voidmain()
{BoxA,B,C;}
该程序运行时调用
(1)次构造函数;调用
(2)次析构函数。
答案:
(1)3
(2)3
分析:
每创建一个对象自动调用一次构造函数,在这里创建了A、B、C三个对象,所以共调用了三次构造函数;每释放一个对象,系统自动调用一次析构函数,A、B、C对象释放时,分别调用析构函数,所以析构函数共调用了三次。
2、设A为test类的对象且赋有初值,则语句testB(A);表示。
答案:
将对象A复制给对象B。
分析:
执行testB(A);语句相当于调用了默认复制构造函数,将A对象的属性复制给B对象。
例题10:
利用“对象名.成员变量”形式访问的对象成员仅限于被声明为
(1)的成员;若要访问其他成员变量,需要通过
(2)函数或(3)函数。
答案:
(1)public
(2)成员函数(3)友元函数
分析:
类体内的数据成员可声明为公有的、私有的和保护的,公有的数据成员可利用“对象名.成员变量”形式来进行访问;私有的数据成员能被类中的其他成员函数或友元函数所调用;保护的数据成员可以在类体中使用,也可以在派生类中使用,但不能在其他类外通过对象使用。
三、改错题
1、分析找出以下程序中的错误,说明错误原因,给出修改方案使之能正确运行。
#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<}
2、分析以下程序的错误原因,给出修改方案使之能正确运行。
#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=>"<}
3、下面的程序定义了一个Point类,找出程序中的错误语句并改正。
#include
classPoint{
intx;
public:
voidPoint(inta)
{x=a;}
intGetx(){returnx;}
voidShow()
{cout<};
voidmain()
{PointA(76);
cout<}
4、根据静态成员的特点,指出下列程序的错误。
#include
#include
classpart
{public:
Part(char*pname=”noname”)
{strncpy(name,pname);
noofpart++;
no=noofpart;
cout<<”createtheno:
”<}
~Part()
{noofpart--;
cout<<”destroytheno:
”<}
staticintnumber(){returnno;}
protected:
staticintnoofpart=0;
intno;
charname[40];
};
voidmain()
{Partp1;
Partp2;
}
5、以下程序的功能是:
利用友员函数为类的成员变量进行初始化,然后利用成员函数输出。
请改正程序中的错误,使之能正确运行。
#include
classA
{inta,b;
public:
friendvoidsetval(inti,intj);
voidshowA()
{cout<};
voidsetval(inti,intj)
{a=i;b=j;}
voidmain()
{Aobj1;
setval(2,3);
obj1.showA();
}
四、写出程序运行结果
1、下列程序的运行结果是。
#include
classpoint
{intx,y;
public:
point(inta,intb)
{x=a;y=b;
cout<<"callingtheconstructorfunction."<}
point(point&p);
friendpointmove(pointq);
~point(){cout<<"callingthedestructorfunction.\n";}
intgetx(){returnx;}
intgety(){returny;}
};
point:
:
point(point&p)
{x=p.x;y=p.y;
cout<<"callingthecopy_initializationconstructorfunction.\n";
}
pointmove(pointq)
{cout<<"OK!
\n";
inti,j;
i=q.x+10;
j=q.y+20;
pointr(i,j);
returnr;
}
voidmain()
{pointm(15,40),p(0,0);
pointn(m);
p=move(n);
cout<<"p="<
}
分析:
根据构造函数、拷贝构造函数和友元函数的特点,执行该程序后,输出结果是:
callingtheconstructorfunction.
callingtheconstructorfunction.
callingthecopy_initializationconstructorfunction.
callingthecopy_initializationconstructorfunction.
OK!
callingtheconstructorfunction.
callingthecopy_initializationconstructorfunction.
callingthedestructorfunction.
callingthedestructorfunction.
callingthedestructorfunction.
P=25,60
callingthedestructorfunction.
callingthedestructorfunction.
callingthedestructorfunction.
说明:
(1)构造函数执行三次,分别初始化主函数中的对象m,p和move函数中的对象r。
(2)拷贝构造函数共执行了三次。
第一次,初始化对象n;第二次在调用函数move()时,实参n给形参q进行初始化;第三次是执行函数move的returnr;语句时,系统用r初始化一个匿名对象时使用了拷贝构造函数。
(3)析构函数执行了六次。
在退出函数move时释放对象r和q共调用二次;返回主函数后,匿名对象赋值给对象p后,释放匿名对象又调用一次析构函数;最后退出整个程序时释放对象m,n和p调用三次。
2、#include
classPoint{
intx,y;
public:
Point(){x=1;y=1;}
~Point(){cout<<"Point"<};
voidmain()
{Pointa;}
运行结果为:
Point1,1isdeleted.
3、#include
#include
intcount=0;
classPoint
{intx,y;
public:
Point()
{x=1;y=1;
count++;
}
~Point(){count--;}
friendvoiddisplay();
};
voiddisplay(){cout<<"Thereare"<voidmain()
{Pointa;
display();
{Pointb[5];
display();
}
display();
}
运行结果为:
Thereare1points,
Thereare6points,
Thereare1points,
4、#include
classCsample
{inti;
public:
Csample();
voidDisplay();
~Csample();
};
Csample:
:
Csample()
{cout<<”Constructor”<<”,”;
i=0;
}
voidCsample:
:
Display(){cout<<”i=”<
Csample:
:
~Csample()
{cout<<”Destructor”<voidmain()
{Csamplea;
a.Display();
}
运行结果为:
Constructor,i=0,Destructor
5、#include
#include
classCsample
{inti;
public:
Csample(){cout<<"constructor1"<Csample(intval){cout<<"Constructor2"<voidDisplay()
{cout<<"i="<
~Csample()
{cout<<"Destructor"<};
voidmain()
{Csamplea,b(10);
a.Display();
b.Display();
}
运行结果为:
Constructor1
Constructor2
i=-858993460
i=10
Destructor
Destructor
6、#include
classCsample
{private:
inti;
staticintk;
public:
Csample();
voidDisplay();
};
intCsample:
:
k=0;
Csample:
:
Csample(){i=0;k++;}
voidCsample:
:
Display(){cout<<”i=”<
voidmain()
{Csamplea,b;
a.Display();
b.Display();
}
运行结果为:
i=0,k=2
i=0,k=2
7、#include
classtest
{public:
test();
test(int);
~test();
voiddisplay();
protected:
intn;
};
test:
:
test(){cout<<”Constructing