类与对象 ●类以及对象的基本概念:类的定义方法,对象的定义方法及其格式 ●成员函数的定义和实现:类的默认构造函数、带参数的构造函数、析构函数、内联函数、 成员函数重载以及设置成员函数的默认值 ·成员:类的静态成员、静态成员函数、友元函数和友元类 选择题 1对类的构造函数和析构函数描述正确的是 A构造函数可以重载,析构函数不能重载B构造函数不能重载,析构函数可以重载 C构造函数可以重载,析构函数能重载 D构造函数不能重载,析构函数也不能重载 答案:A 2假定MyClass为一个类,则该类的拷贝初始化构造函数的声明语句为 A MyClass&(MyClass x):B MyClass(MyClass x): C MyClass(MyClass &x);D MyClass(MyClass *x) 答案C 注释:拷贝初始化构造函数的一般形式如下: ::(const&) 拷贝构造函数体 3下面对于友元函数描述正确的是_ A友元函数的实现必须在类的内部定义 B友元函数是类的成员函数 C 友元函数破坏了类的封装性和隐藏性 D友元函数不能访问类的私有成员 答案C 注释:友元函数虽然在类的定义中声明,但它不是类的成员函数,友元函数的参数通常是类 的对象。一个类的友元函数或友元类能够通过成员操作符访问该类的所有成员。 4下面对静态数据成员的描述中,正确的是 A静态数据成员是类的所有对象共享的数据 B类的每个对象都有自己的静态数据成员 类的不同对象有不同的静态数据成员值 D静态数据成员不能通过类的对象调用 答案A 注释:类的不同对象的属性占据不同的内存空间,而类的不同对象共享静态数据成员,它们 拥有相同的静态数据成员的内存空间。 静态数据成员应该在文件范围内初始化,即应该在类体外进行初始化。静态数据成员的初始 化与它的访问控制权限无关,但对静态数据成员的访问则受到访问权限的限制。静态数据成 员是类的所有对象共享的成员,即可以通过类名访问,也可以通过对象访问。但通过类名访 1
类与对象 z 类以及对象的基本概念:类的定义方法,对象的定义方法及其格式 z 成员函数的定义和实现:类的默认构造函数、带参数的构造函数、析构函数、内联函数、 成员函数重载以及设置成员函数的默认值 z 成员:类的静态成员、静态成员函数、友元函数和友元类 选择题 1 对类的构造函数和析构函数描述正确的是 A 构造函数可以重载,析构函数不能重载 B 构造函数不能重载,析构函数可以重载 C 构造函数可以重载,析构函数能重载 D 构造函数不能重载,析构函数也不能重载 答案:A 2 假定 MyClass 为一个类,则该类的拷贝初始化构造函数的声明语句为 A MyClass&(MyClass x); B MyClass (MyClass x); C MyClass ( MyClass &x); D MyClass (MyClass *x) 答案 C 注释:拷贝初始化构造函数的一般形式如下: ::(const&) { //拷贝构造函数体 } 3 下面对于友元函数描述正确的是 A 友元函数的实现必须在类的内部定义 B 友元函数是类的成员函数 C 友元函数破坏了类的封装性和隐藏性 D 友元函数不能访问类的私有成员 答案 C 注释:友元函数虽然在类的定义中声明,但它不是类的成员函数,友元函数的参数通常是类 的对象。一个类的友元函数或友元类能够通过成员操作符访问该类的所有成员。 4 下面对静态数据成员的描述中,正确的是 A 静态数据成员是类的所有对象共享的数据 B 类的每个对象都有自己的静态数据成员 C 类的不同对象有不同的静态数据成员值 D 静态数据成员不能通过类的对象调用 答案 A 注释:类的不同对象的属性占据不同的内存空间,而类的不同对象共享静态数据成员,它们 拥有相同的静态数据成员的内存空间。 静态数据成员应该在文件范围内初始化,即应该在类体外进行初始化。静态数据成员的初始 化与它的访问控制权限无关,但对静态数据成员的访问则受到访问权限的限制。静态数据成 员是类的所有对象共享的成员,即可以通过类名访问,也可以通过对象访问。但通过类名访 1
问更方便、更高效。 5下面是类MyClass的定义,对定义中语句描述正确的是一 class MyClass { public: void MyClass (int a)(X=a') 11@ int f(int a int b) 11② { X=a; Y=b: } int f(int a.int b.int c=0) 1/③ { X=a, Y=b; Z=c, } static void g(){X=10;} 11④ private: int X,Y,Z; : A语句①是类MyClass的构造函数定义 B语句②和语句③实现类成员函数的重载 C语句④实现对类成员变量X的更新操作 D语句①、②、③和④都不正确 答案D 注释:语句①不应该有返回类型vod:语句②和语句③不能实现成员函数重载,调用函数 f10,20)时会产生二义性:语句④,静态成员函数不能直接操作类的非静态数据成员。 填空 1在C语言中,编程的单位是函数:在C十十语言中,编程的单位是类。 2类是对具有共同属性和行为的一类事物的抽象描述,共同属性被描述为类中的数据成员, 共同行为被描述为类中的成员函数。 3类的具体实现是通过定义对象来操作的。 4类中的构造函数是一个特殊的成员函数,它由类的对象自动调用,它的作用是为对象分配 内存空间,为类的数据成员进行初始化并进行一些其他类的内部操作。 4在定义类的对象时,C十十程序将自动调用该对象的构造函数初始化对象自身,在撤销 类的对象时,C十十程度将自己调用该对象的析构函数 5非成员函数应声明为类的友元函数才能访问该类的private成员:若要把类FriendClass定 义为类MyClass的友元类,则应在MyClassl的定义中加入语句friend Class FriendClass,:若 要把函数void FriendFunction()定义为类MyClass的友元函数,则应在类MyClass的定义中 加入语句friend void FriendFunction( 6在下面程序的横线处填上适当的语句,使该程序执行结果为10。 2
问更方便、更高效。 5 下面是类 MyClass 的定义,对定义中语句描述正确的是 class MyClass { public: void MyClass (int a) {X=a’} //① int f(int a,int b) //② { X=a; Y=b; } int f(int a,int b,int c=0) //③ { X=a; Y=b; Z=c; } static void g() { X=10;} //④ private: int X,Y,Z; }; A 语句①是类 MyClass 的构造函数定义 B 语句②和语句③实现类成员函数的重载 C 语句④实现对类成员变量 X 的更新操作 D 语句①、②、③和④都不正确 答案 D 注释: 语句①不应该有返回类型 void;语句②和语句③不能实现成员函数重载,调用函数 f(10,20)时会产生二义性;语句④,静态成员函数不能直接操作类的非静态数据成员。 填空 1 在C语言中,编程的单位是函数;在C++语言中,编程的单位是类。 2 类是对具有共同属性和行为的一类事物的抽象描述,共同属性被描述为类中的数据成员, 共同行为被描述为类中的成员函数。 3 类的具体实现是通过定义对象来操作的。 4 类中的构造函数是一个特殊的成员函数,它由类的对象自动调用,它的作用是为对象分配 内存空间,为类的数据成员进行初始化并进行一些其他类的内部操作。 4 在定义类的对象时,C++程序将自动调用该对象的构造函数初始化对象自身,在撤销 类的对象时,C++程度将自己调用该对象的析构函数 5 非成员函数应声明为类的友元函数才能访问该类的private成员;若要把类FriendClass定 义为类MyClass的友元类,则应在MyClass的定义中加入语句friend Class FriendClass; 若 要把函数void FriendFunction()定义为类MyClass的友元函数,则应在类MyClass的定义中 加入语句friend void FriendFunction(); 6 在下面程序的横线处填上适当的语句,使该程序执行结果为 10。 2
include class MyClass { public: 1 MyClass(int a ){x=a: /为x置值 2 int GetNum(){return x:} /取x值 private: int x; } void main() { MyClass my(10); Cout class Sample { int x,y; public: Sample(){x=y=0;) Sample(int a,int b){x=a;y=b;) Void disp() { cout class Sample 3
# include class MyClass { public: ① MyClass(int a ){x=a;} //为x置值 ② int GetNum() {return x;} //取x值 private: int x; } void main() { MyClass my(10); Cout class Sample { int x,y; public: Sample(){x=y=0;} Sample(int a, int b) {x=a;y=b;} Void disp() { cout class Sample 3
int x,y; public: Sample(){x=y=0;) Sample(int a,int b){x=a;y=b;) ~Sample() if(x=可y) cout class Sample int n; static int sum; public: Sample (int x)n=x; void add(){sum+=n; void disp() { cout<<"n=”<<n<<”,Sum=”<<sum<<endl:
{ int x,y; public: Sample(){x=y=0;} Sample(int a, int b) {x=a;y=b;} ~Sample() { if (x= =y) cout class Sample { int n; static int sum; public: Sample (int x){n=x;} void add(){sum+=n;} void disp() { cout<<”n=”<<n<<”,sum=”<<sum<<endl; } 4
int Sample:sum=0,/静态数据成员赋初值 void main() { Sample a(2),b(3),c(5); a.add(): a.disp(); b.add(); b.disp(); c.add(): c.disp(); } 答案:本题说明静态数据成员的使用方法。在类中定义了一个静态数据成员sum,在main ()之前给它赋初值0,然后在main()中定义了三个对象,并执行各自的add()和disp ()方法,所以输出为: n=2,sum=2 n=3,sum=5 n=5,sum=10 注意:静态数据成员脱离具体的对象独立存在,其存储单元不是任何对象存储空间的一部分, 但逻辑上所有对象都共享这一存储单元,对静态数据成员的任何操作都会访问这一存储单 元,从而影响这一存储单元的所有对象,所以说静态数据成员不是对象成员,在引用时不需 使用对象名。 程序4 include class Sample int A: static int B: public Sample (int a)A=a;B+=a; Static void func(Sample s) }, void Sample::func(Sample s) { cout<<”A=”<<s.A<<,B=”<<B<<endl; } int Sample:B=0: void main() { Sample s1(2).s2(5); Sample::func(s1); Sample::func(s2); 5
}; int Sample::sum=0; //静态数据成员赋初值 void main() { Sample a(2),b(3),c(5); a.add(): a.disp(); b.add(); b.disp(); c.add(); c.disp(); } 答案:本题说明静态数据成员的使用方法。在类中定义了一个静态数据成员 sum,在 main ()之前给它赋初值 0,然后在 main()中定义了三个对象,并执行各自的 add()和 disp ()方法,所以输出为: n=2,sum=2 n=3,sum=5 n=5,sum=10 注意:静态数据成员脱离具体的对象独立存在,其存储单元不是任何对象存储空间的一部分, 但逻辑上所有对象都共享这一存储单元,对静态数据成员的任何操作都会访问这一存储单 元,从而影响这一存储单元的所有对象,所以说静态数据成员不是对象成员,在引用时不需 使用对象名。 程序 4 # include class Sample { int A; static int B; public: Sample (int a){A=a; B+=a;} Static void func(Sample s) }; void Sample::func(Sample s) { cout<<”A=”<<s.A<<”,B=”<<B<<endl; } int Sample::B=0; void main() { Sample s1(2),s2(5); Sample::func(s1); Sample::func(s2); } 5
答案:本题说明静态成员函数的使用方法。其中的数据成员B是静态数据成员,求B的值 是在构造函数中进行的。所以输出为: A=2,B=7 A=5,B=7 注意:静态成员函数与静态数据成员一样,也不是对象成员。静态成员函数的调用不同于普 通成员函数。在静态成员函数的实现中,引用类的非静态数据成员是通过对象进行的,如本 题中的s.A:应用类的静态数据成员是直接进行的,如本题中的B。 程序设计题 1设计一个立方体类Box,它能计算并输出立方体的体积和表面积。 Box类包含三个私有数据成员a(立方体边长)、volume(体积)和area(表面积),另有两 个构造函数以及seta()(设置立方体边长)、getvolume()(计算体积)、getarea()(计算 表面积)和disp()(输出结果)。本题程序如下: #include class Box float a; float volume; flaot area; public: Box() Box(float r)(a=r;) void seta(float r)a=r; void getvolume ()volume=a*a*a; void getarea ()farea=6*a*a;} void disp() { cout”, obj1.disp(); obj2.getvoulme(); obj2.getarea(); cout”, obj2.disp(); 本程序执行结果: 6
答案:本题说明静态成员函数的使用方法。其中的数据成员 B 是静态数据成员,求 B 的值 是在构造函数中进行的。所以输出为: A=2,B=7 A=5,B =7 注意:静态成员函数与静态数据成员一样,也不是对象成员。静态成员函数的调用不同于普 通成员函数。在静态成员函数的实现中,引用类的非静态数据成员是通过对象进行的,如本 题中的 s.A;应用类的静态数据成员是直接进行的,如本题中的 B。 程序设计题 1 设计一个立方体类 Box,它能计算并输出立方体的体积和表面积。 Box 类包含三个私有数据成员 a(立方体边长)、volume(体积)和 area(表面积),另有两 个构造函数以及 seta()(设置立方体边长)、getvolume()(计算体积)、getarea()(计算 表面积)和 disp()(输出结果)。本题程序如下: #include class Box { float a; float volume; flaot area; public: Box() {} Box(float r) {a=r;} void seta(float r) {a=r;} void getvolume () {volume=a*a*a;} void getarea () {area=6*a*a; } void disp() { cout”; obj1.disp(); obj2.getvoulme(); obj2.getarea(); cout”; obj2.disp(); } 本程序执行结果: 6
obi1=>体积:91.125,表面积:121.5 obj2=>体积:262.144,表面积:245.76 2编写一个程序,输入N个学生数据,包括学号、姓名、成绩,要求只输出成绩在80~ 89分数段的学生数据。 设计一个学生类Stud,包括no(学号)、name(姓名)和deg(成绩)数据成员,另有两个 普通成员函数setdata()和disp(),前者用于设置对象数据,后者用于只输出成绩在80~ 89分数段的学生数据。在main()函数中定义了一个对象数组,用于存储输入的学生数据。 本题程序如下: #include include #define N 3 class Stud { int no; char name[10]; int deg; public: void setdata(int n,char nan],int d) { no=n;deg=d; strcpy(name,na); } void disp() { if(deg>=80&°<=89) printf(“%-5d%-8s%3dn”,no,name,deg; void main() Stud st[N]; int i,n,d; char na10]: for(i=0;i<N;i++) printf(输入学号姓名成绩:“): scanf“%d%s%d”,&n,na,&d): st i].setdata(n,na,d): } printf“输出数据n”), printf“学号姓名成绩n"); for(i=0.i<N:i++) 1
obj1=>体积:91.125,表面积:121.5 obj2=>体积:262.144,表面积:245.76 2 编写一个程序,输入 N 个学生数据,包括学号、姓名、成绩,要求只输出成绩在 80~ 89 分数段的学生数据。 设计一个学生类 Stud,包括 no(学号)、name(姓名)和 deg(成绩)数据成员,另有两个 普通成员函数 setdata()和 disp(),前者用于设置对象数据,后者用于只输出成绩在 80~ 89 分数段的学生数据。在 main()函数中定义了一个对象数组,用于存储输入的学生数据。 本题程序如下: #include # include #define N 3 class Stud { int no; char name[10]; int deg; public: void setdata( int n, char na[], int d) { no=n;deg=d; strcpy(name,na); } void disp() { if (deg>=80 && deg<=89) printf(“ %-5d%-8s%3d\n”,no,name,deg); } }; void main() { Stud st[N]; int i,n,d; char na[10]; for ( i=0;i<N;i++) { printf(“输入学号 姓名 成绩:“); scanf(“%d%s%d”, &n,na,&d); st[i].setdata(n,na,d); } printf(“输出数据\n”); printf(“ 学号 姓名 成绩\n”); for( i=0,i<N;i++) 7
st[i].disp(); 本程序执行结果: 输入学号姓名成绩: 1 stud1 78 输入学号姓名成绩: 2stud285∠ 输入学号姓名成绩: 3stud389∠ 输出数据 学号姓名 成绩 stud2 85 3 stud3 89 8
st[i].disp(); } 本程序执行结果: 输入学号 姓名 成绩: 1 stud1 78↙ 输入学号 姓名 成绩: 2 stud2 85↙ 输入学号 姓名 成绩: 3 stud3 89↙ 输出数据 学号 姓名 成绩 2 stud2 85 3 stud3 89 8