西安石油大学大二(上)C++面向对象程序设计课件各章习题 下载本文

习题1

基本概念题: 9.1 填空题:

(1) 一个完整的可运行程序中必须有一个名为________的函数。 (2) 一条表达式语句必须以________作为结束符。 (3)一个函数定义由________和________两部分组成。

(4)若一个函数的定义处于调用它的函数之前,则在程序开始可以省去该函数的________语句。

(5)C++头文件和源程序文件的扩展名分别为________和________。 (6)程序文件的编译错误分为________和_________两类。

(7)当使用________保留字作为函数类型时,该函数不返回任何值。 (8)当函数参数表用_________保留字表示时,则表示该参数表为空。

(9)从一条函数原型语句“int fun1(void);”可知,该函数的返回类型为________,该函数带有________个参数。

(10)在#include命令中所包含的头文件,可以是系统定义的头文件,也可以是________定义的头文件。

(11)重载一个函数的条件是:该函数必须在参数的个数或参数的__________上与其它同名函数有所不同。

(12)如果一个函数中有多个默认参数,则默认参数必须全部处在形参表的________部分。

(13)函数形参的作用域是该函数的____________。

(14)当定义一个结构体变量时,系统分配给该变量的内存大小等于各成员所需内存大小的_______。

9.2 选择题:

(1)以下说法中正确的是( )。

A. C++程序总是从第一个定义的函数开始执行 B. C++程序总是从main函数开始执行

C. C++函数必须有返回值,否则不能使用函数

D. C++程序中有调用关系的所有函数必须放在同一个程序文件中 (2)以下叙述中不正确的是( )。

A. 在一个函数中,可以有多条return语句

B. 函数的定义不能嵌套,但函数的调用可以嵌套 C. 函数必须有返回值

D. 不同的函数中可以使用相同名字的变量 (3)函数重载是指( )。

A. 两个或两个以上的函数取相同的函数名,但形参的个数或类型不同

1

B. 两个以上的函数取相同的名字和具有相同的参数个数,但形参的类型可以不同

C. 两个以上的函数名字不同,但形参的个数或类型相同

D. 两个以上的函数取相同的函数名,并且函数的返回类型相同 (4)下列( )的调用方式是引用调用。

A. 形参和实参都是变量 B.形参是指针,实参是地址值 C. 形参是引用,实参是变量 D.形参是变量,实参是地址值

(5)为了提高程序的运行速度,可将不太复杂的功能用函数实现,此函数应选择( )。

A. 内联函数 B.重载函数 C.递归函数 D.函数模板 (6)C++中函数返回值的类型是由( )决定的。

A. return语句中表达式的类型 B.该函数定义时的类型 C.调用函数时的调用语句 D.系统根据结果 (7)以下函数的返回结果是( )。

int function(char *x) {

char *p=x; while(*p++); return(p-x-1); }

A. 求字符串的长度 B.将字符串x连接到字符串p后面 C. 将字符串x复制到字符串p中 D.将字符串x反向存放 (8)以下正确的函数原型语句是( )。

A. double fun(int x,int y) B. double fun(int x;int y) C. double fun(int,int); D. double fun(int x,y);

(9)以下正确的描述是( )。

A. 函数的定义可以嵌套,函数的调用不可以嵌套 B. 函数的定义不可以嵌套,函数的调用可以嵌套 C. 函数的定义和函数的调用均可以嵌套 D. 函数的定义和函数的调用均不可以嵌套

(10)若用数组名作为函数调用的实参,传递给形参的是( )。 A. 数组的首地址 B. 数组中第一个元素的值 C. 数组全部元素的值 D. 数组元素的个数 (11)以下正确的描述是( )。 A. 不允许设置参数的默认值

B. 设置参数的默认值只能在定义函数时设置 C. 设置参数的默认值时,应该设置右边的参数 D. 设置参数的默认值时,应该全部参数都设置 (12)采用重载函数的目的是( )。

2

A. 实现共享 B. 减少空间

C. 提高速度 D. 使用方便,提高可读性

(13)当#include后面的文件名用双引号括起来时,寻找被包含文件的方式是( )。

A. 直接按系统设定的标准方式搜索目录

B. 先在源程序所在目录搜索,再按系统设定的标准方式搜索目录 C. 仅仅搜索源程序所在目录

D. 搜索当前逻辑盘上的所有目录

(14)当#include后面的文件名用尖括号括起来时,寻找被包含文件的方式是( )。

A. 直接按系统设定的标准方式搜索目录

B. 先在源程序所在目录搜索,再按系统设定的标准方式搜索目录 C. 仅仅搜索源程序所在目录

D. 搜索当前逻辑盘上的所有目录

(15) 文件包含命令中被包含的文件的扩展名( )。

A. 必须是.h B. 不能是.h C. 可以是.h或.cpp D. 必须是.cpp (16)下列对引用的陈述中不正确的是( )。

A. 每一个引用都是其所引用对象的别名,因此必须初始化 B. 形式上针对引用的操作实际上作用于它所引用的对象

C. 一旦定义了引用,一切针对其所引用对象的操作只能通过该引用间接进行 D. 不需要单独为引用分配存储空间 (17)若需要把一个类外定义的成员函数指明为内联函数,则必须把关键字( )放在函数原型或函数头的前面。

A. in B. inline C. inLine D. InLiner (18)在多文件结构的程序中,通常把类的定义单独存放于( )中。 A. 主文件 B. 实现文件 C. 库文件 D. 头文件 (19)在多文件结构的程序中,通常把含有main()函数的文件称为( )。 A. 主文件 B. 实现文件 C. 程序文件 D. 头文件 (20)一个C++程序文件的扩展名为( )。 A. .h B. .c C. .cpp D. .cp 9.3 C++/C语言的基本数据类型有哪些?写出它们各自的关键字。 9.4 C++/C语言的基本语句有哪些?写出它们各自的语法格式。 9.5 C++语言的枚举类型和C语言的枚举类型有什么不同? 9.6 C++语言的结构体类型和C语言的结构体类型有什么不同?

9.7 和C语言变量的定义方法相比,C++语言变量的定义方法有什么改进? 9.8 在一个变量的定义前加const关键字有什么作用? 9.9 函数怎样体现了程序的模块化设计?

9.10 什么叫函数的形参?什么叫函数的实参?

3

9.11 什么叫输入型参数?怎样设计函数的输入型参数? 9.12 什么叫输出型参数?怎样设计函数的输出型参数?

9.13 怎样把系统库函数和用户自定义函数包含到一个程序中? 9.14 什么叫函数原型?函数原型机制有什么优点?

9.15 什么叫内联函数?怎样定义内联函数?什么样的函数可以定义成内联函数?

9.16 怎样设计带缺省参数的函数?试举一例说明。 9.17 什么叫函数重载?重载的函数要满足什么条件? 9.18 怎样定义引用变量?引用变量有什么功能?

9.19 说明在设计函数时,怎样利用引用变量设计输出型参数?在调用函数时,怎样设计相应的实际参数? 9.20 自定义语句有什么用途?

9.21 程序预处理主要完成哪些工作?

9.22 如果一个程序中包含有#include语句行,则该程序的编译和运行过程是怎样的?

9.23 与用malloc()函数和free ()函数进行存储单元的动态申请和释放相比,用new运算符和delete运算符进行存储单元的动态申请和释放有什么优点?

程序阅读和设计题:

9.24 阅读程序,给出运行结果:

(1)

#include \int m=10; void a(int n) { }

void main() {

int n=3; }

a(n);

cout<<\

n=15/n; m=m/2;

(2)

#include \int count(double *a) {

4

double *p=a; while(*p!=0)

p++; return (p-a);

}

void main() { double a[]={1.0,2.0,8.0,3.0,0.0,4.0,7.0}; cout<

3)

#include \bool isprime(int m) { for (int i=2;m%i!=0;i++) {}

return (i==m);

}

void main() {

int m=3;

while(isprime(m)) { cout<<\

m++;

}

cout<<\}

4)

#include \#include \int sum(int a[],int n) { for(int s=0,i=0;i

}

5

((

return s;

}

void main() { int i,a[]={5,4,3,2,1}; cout<

5)

#include \#include \void f(int *p,int n) { for(int i=0;i

}

}

void main() { int i,a[]={0,1,2,3,4},*p=&a[0]; f(p,2);

for(i=0;i<5;i++)

cout<

6)

#include \int x=5; int p(int x) {

int y=1;

static int z=1; y++;z++; return x+y+z; }

void main( ) {

6

((

for(int i=1;i<3;i++) cout<

9.25 编写一个求n×n方阵主对角元素之和的函数。并设计一个测试主函数。 说明:可以使用以前学过的程序开发工具,也可以阅读掌握附录的Visual C++集成开发环境,并用这样的开发环境开发程序。

9.26 编写一个求n×n方阵主对角元素之和以及非主对角元素之和的函数。并设计一个测试主函数。

9.27 在自己的计算机上安装Visual C++集成开发环境,阅读附录1的Visual C++集成开发环境,熟悉该集成开发环境的使用方法。

9.28 编写一个把有n个元素的数组a中的元素逆置保存到数组b的函数,并设计一个测试主函数进行测试。

9.29 阅读附录2的程序调试技术,以习题1.29为例,练习调试程序的基本技术。 9.30 编写一个把有n个元素的数组a中的元素就地逆置的函数,所谓就地逆置就是逆置后的元素还保存在数组a中。并设计一个测试主函数进行测试。

7

习题2

基本概念题: 9.1 填空题:

(1)以面向对象方法构造的系统,其基本单位是__________。 (2)每个对象都是所属类的一个__________。

(3)对象将其大部分实现细节隐藏起来,这种机制称为__________。

(4)对象是对问题域中客观事物的________,它是一组属性和在这些属性上操作的________。

(5)特殊类的对象拥有其一般类的全部属性与操作,称特殊类________了一般类。 (6)面向对象软件开发的生命周期分为三个阶段,即分析、________和________。 9.2 选择题:

(1)关于消息,下列说法中不正确的是( )。

A. 发送消息的对象请求服务,接受消息的对象提供服务 B. 消息的发送者必须了解消息的接收者如何相应消息

C. 在C++中,消息的发送具体体现为对接收消息的对象的某个函数的调用 D. 每个对象只能接收某些特定格式的消息 (2)关于封装,下列说法中不正确的是( )。

A. 通过封装,对象的全部属性和操作结合在一起,形成一个整体 B. 通过封装,一个对象的实现细节被尽可能地隐藏起来(不可见) C. 通过封装,每个对象都成为相对独立的实体 D. 通过封装,对象的属性都是不可见的 (3)面向对象方法的多态性是指( )。 A. 一个类可以派生出多个特殊类

B. 一个对象在不同的运行环境中可以有不同的变体

C. 针对一消息,不同的对象可以以适合自身的方式加以响应 D. 一个对象可以是由多个其他对象组合而成的

(4)软件产品在需求发生变化、运行环境发生变化或发现软件产品本身的错误或不足时进行相应的软件更新的难易程度叫做软件的( )。

A. 可维护性 B. 可复用性 C. 兼容性 D. 正确性

(5)软件产品可被全部或部分地再用于新的应用的能力叫做软件的( )。 A. 可维护性 B. 可复用性 C. 兼容性 D. 正确性

(6)软件产品与其他软件产品组合成一个整体的难易程度叫做软件的( )。 A. 可维护性 B. 可复用性 C. 兼容性 D. 正确性

(7)软件产品准确执行软件需求规格说明书中所规定的任务的能力叫做软件的( )。

A. 可维护性 B. 可复用性 C. 兼容性 D. 正确性

8

(8)关于面向对象系统分析,下列说法中不正确的是( )。 A. 术语“面向对象分析”可以用缩写OOA表示

B. 面向对象分析阶段对问题域的描述比实现阶段更详细 C. 面向对象分析包括问题域分析和应用分析两个步骤 D. 面向对象分析需要识别对象的内部和外部特征 9.3 简述面向过程程序设计的基本思想。 9.4 简述面向过程软件开发方法的主要问题。

9.5 简述例2.1的C语言面向过程程序和C++语言面向对象程序的不同。 9.6 什么叫类?什么叫类的实例?类和类的实例的关系是怎样的? 9.7 什么叫消息?什么叫事件?

9.8 解释面向对象的抽象性、封装性、继承性和多态性。 9.9 多态性有几种?各自的定义是什么?

9.10 什么叫整体——部分模式?什么叫一般——特殊模式?

9.11 叙述子类对父类中方法的继承中,完全继承、扩充继承和覆盖继承三种不同的设计方法各有什么意义?

9.12 面向对象分析阶段要完成怎样的工作? 9.13 面向对象设计阶段要完成怎样的工作? 9.14 面向对象实现阶段要完成怎样的工作? 9.15 简述面向对象程序设计的优点。

复杂概念题:

9.16 分析复数在实际应用中的应用情况,用面向对象方法分析复数。要求画出复数的对象模型图,即画出复数类的类名、属性和行为。

9.17 学习过数据结构课程的学生已经熟悉堆栈的概念,用面向对象方法分析一个堆栈。要求画出堆栈的对象模型图,即画出堆栈类的类名、属性和行为。 9.18 学习过数据结构课程的学生已经熟悉队列的概念,用面向对象方法分析一个队列。要求画出队列的对象模型图,即画出队列类的类名、属性和行为。 9.19 调查学校图书馆的管理和使用方法,用面向对象方法分析一个简单的图书管理系统。要求画出图书管理系统的对象模型图,即画出所有的类(包括类名、属性和行为)以及类之间的联系方式。

9.20 调查学校教务处的管理和学生学籍查询方法,用面向对象方法分析一个简单的教务管理系统。要求画出教务管理系统的对象模型图,即画出所有的类(包括类名、属性和行为)以及类之间的联系方式。

程序设计题:

9.21 在例2.1的基础上,分别设计完成实现复数乘除功能的C语言程序和C++语言面向对象程序。并要求完成复数(1,1)和复数(2,2)的乘除运算并输出运算结果。

9

习题3

基本概念题: 9.1 填空题:

(1)类定义中,既包含成员变量,也包含________。 (2)类中成员变量的访问属性通常定义为________。

(3)类中的供外部调用定义的成员函数,其访问属性通常被定义为________。 (4)对于类中定义的任何成员,其隐含访问权限为________。 (5)对于结构体中定义的任何成员,其隐含访问权限为________。

(6)若在类的定义体中给出了一个成员函数的完整定义,则该成员函数属于________函数。

(7)若在类的定义体中只给出了一个成员函数的原型,则在类外给出完整定义时,其函数名前必须加上________和两个冒号分隔符。

(8)若要把类外定义的成员函数规定为内联函数,则必须把________关键字放到函数原型或函数头的前面。

(9)把一个类的定义体和所有成员函数的定义体所构成的程序范围叫做该类的____________。

(10)假定AA是一个类,“AA* abc();”是该类中一个成员函数的原型,则在类外定义时的函数头为__________________。

(11)成员函数的所有参数在类的作用域中,成员函数的返回值________类作用域。

(12)若只需要通过一个成员函数读取成员变量的值,而不需要修改它,则应在函数头的后面加上________关键字。

(13)一个类的__________函数实现对该类对象的初始化功能。

(14)一个类的__________函数通常用于实现释放该类对象中指针成员所指向的动态存储空间的任务。

(15)创建类的动态对象数组时,其元素只能靠自动调用该类的____________来进行初始化。

(16)在一个类中定义拷贝构造函数的目的,是为了当利用该类的一个对象初始化另一个对象时,能够避免这两个对象的同一指针同时指向同一块__________。

(17)假定AB类中只包含一个整型成员变量a,并且它是一个常量成员,若利用参数aa对其进行初始化,则该类的构造函数的定义为____________________。

(18)假定指针p指向一个动态分配的类对象,则当执行“delete p;”语句时,在释放p所指向的动态存储空间之前将自动调用该类的____________。

(19)假定用户为类AB定义了一个构造函数“AB(int aa) {a=aa;}”,则系统(会/不会)_________为该类自动定义一个无参构造函数\。

(20)假定用户为类AB定义了一个构造函数“AB(int aa, char

10

*bb=NULL):a(aa),b(bb){}”,则该类中至少包含有__________个成员变量。

(21)假定用户为类AB定义了一个构造函数“AB(int aa) {a=aa;}”,该构造函数实现对成员变量_________的初始化。

(22)假定用户为类AB定义了一个构造函数“AB(int aa=0):a(aa){}”,则创建该类的对象时,可以有________种不同的格式。

(23)假定用户只为类AB定义了一个构造函数“AB(int aa, int bb=0) {a=aa; b=bb;}”,则创建该类的对象时,其实参表中至多带有_________个实参。

(24)假定用户只为类AB定义了一个构造函数“AB(int aa, int bb=0) {a=aa; b=bb;}”,则创建该类的对象时,其实参表中至少带有_________个实参。

(25)假定用户为类AB定义了一个构造函数“AB(int aa=0, int bb=0) {a=aa; b=bb;}”,则创建该类的对象时,可以有________种不同的格式。

(26)假定用户只为类AB定义了一个构造函数“AB():a(0),b(0){}”,则创建该类对象x的语句“AB x();”是_________(正确/错误)的。

(27)假定用户只为类AB定义了一个构造函数“AB():a(0),b(0){}”,则创建该类对象x的语句“AB x;”是_________(正确/错误)的。

(28)假定用户只为类AB定义了一个构造函数“AB():a(0),b(0){}”,则创建该类对象x的语句“AB x(5);”是_________(正确/错误)的。

(29)假定AB为一个类,则该类的拷贝构造函数的函数头为_____________。 (30)假定AB为一个类,该类中含有一个指向动态数组空间的指针成员pa,则在该类的析构函数中应该包含有一条______________语句。

(31) 静态成员函数 ____访问类的静态成员变量, ____ 访问类的非静态成员变量。

(32)静态成员变量必须在所有函数的定义体外进行__________。 9.2 选择题:

(1)在类作用域中能够通过直接使用该类的( )成员名进行访问。 A. 私有 B. 公有 C. 保护 D. 任何 (2)在关键字public后面定义的成员为类的( )成员。 A. 私有 B. 公有 C. 保护 D. 任何 (3)在关键字private后面定义的成员为类的( )成员。 A. 私有 B. 公有 C. 保护 D. 任何

(4)假定AA为一个类,a为该类公有的成员变量,x为该类的一个对象,则访问x对象中成员变量a的格式为( )。

A. x(a) B. x[a] C. x->a D. x.a

(5)假定AA为一个类,a()为该类公有的成员函数,x为该类的一个对象,则访问x对象中成员函数a()的格式为( )。

A. x.a B. x.a() C. x->a D. x->a()

(6)假定AA为一个类,a为该类公有的成员变量,px为指向该类对象的一个指针,则访问px所指对象中成员变量a的格式为( )。

11

A. px(a) B. px[a] C. px->a D. px.a

(7)假定AA为一个类,a为该类私有的成员变量,GetValue()为该类公有成员函数,它返回a的值,x为该类的一个对象,则访问x对象中成员变量a的格式为( )。

A. x.a B. x.a() C. x->GetValue() D. x.GetValue() (8)假定AA为一个类,int a()为该类的一个成员函数,若该成员函数在类定义体外定义,则函数头为( )。

A. int AA::a() B. int AA:a() C. AA::a() D. AA::int a()

(9)假定AA为一个类,a为该类公有的成员变量,若要在该类的一个成员函数中访问它,则书写格式为( )。

A. a B. AA::a C. a() D. AA::a() (10)假定AA是一个类,“AA* abc()const;”是该类中一个成员函数的原型,若该函数返回this值,当用x.abc()调用该成员函数后,x的值( )。

A. 已经被改变 B. 可能被改变

C. 不变 D. 受到函数调用的影响 (11)类中定义的成员默认为( )访问属性。

A. public B. private C. protected D. friend (12)结构体中定义的成员默认为( )访问属性。

A. public B. private C. protected D. friend (13)对于一个类的构造函数,其函数名与类名( )。

A. 完全相同 B. 基本相同 C. 不相同 D. 无关系 (14)对于一个类的析构函数,其函数名与类名( )。

A. 完全相同 B. 完全不同 C. 只相差一个字符 D. 无关系 (15)类的构造函数是在定义该类的一个( )时被自动调用执行的。 A. 成员函数 B. 成员变量 C. 对象 D. 友元函数 (16)类的析构函数是一个对象被( )时自动调用的。 A. 建立 B. 撤消 C. 赋值 D. 引用 (17)一个类的构造函数通常被定义为该类的( )成员。 A. 公有 B. 保护 C. 私有 D. 友元 (18) 一个类的析构函数通常被定义为该类的( )成员。 A. 私有 B. 保护 C. 公有 D. 友元

(19)假定AB为一个类,则执行 “AB x;”语句时将自动调用该类的( )。 A. 带参构造函数 B. 无参构造函数

C. 拷贝构造函数 D. 赋值重载函数

(20)假定AB为一个类,则执行 “AB x(a,5);”语句时将自动调用该类的( )。 A. 带参构造函数 B. 无参构造函数 C. 拷贝构造函数 D. 赋值重载函数

(21)假定AB为一个类,则执行 “AB *s=new AB(a,5);”语句时得到的一个动态

12

对象为_______。

A. s B. s->a C. s.a D. *s

(22)假定AB为一个类,则执行 “AB r1=r2;”语句时将自动调用该类的( )。 A. 无参构造函数 B. 带参构造函数 C. 赋值重载函数 D. 拷贝构造函数 (23)若需要使类中的一个指针成员变量指向一块动态存储空间,则通常在( )函数中完成。

A. 析构 B. 构造 C. 任一成员 D. 友元

(24)当类中的一个整型指针成员指向一块具有n*sizeof(int)大小的存储空间时,它最多能够存储( )个整数。

A. n B. n+1 C. n-1 D. 1

(25)假定一个类的构造函数为 “A(int aa, int bb) {a=aa; b=aa*bb;}”,则执行 “A x(4,5);”语句后,x.a和x.b的值分别为( )。

A. 4和5 B. 5和4 C. 4和20 D. 20和5

(26)假定一个类的构造函数为 “A(int aa=1, int bb=0) {a=aa; b=bb;}”,则执行 “A x(4);”语句后,x.a和x.b的值分别为( )。

A. 1和0 B. 1和4 C. 4和1 D. 4和0

(27)假定AB为一个类,则( )为该类的拷贝构造函数的原型说明。 A. AB(AB x); B. AB(AB& x); C. void AB(AB& x); D. AB(int x); (28)假定一个类的构造函数为 “B(int ax, int bx): a(ax), b(bx) {}”,执行 “B x(1,2),y(3,4);x=y;”语句序列后x.a的值为( )。

A. 1 B. 2 C. 3 D. 4 (29)假定一个类AB只含有一个整型成员变量a,当用户不定义任何构造函数时,系统为该类定义的无参构造函数为( )。

A. AB() {a=0;} B. AB(int aa=0): a(aa) {} C. AB(int aa): a(aa) {} D. AB() {}

(30)假定一个类AB只含有一个整型成员变量a,用户为该类定义的带参构造函数可以为( )。

A. AB() {} B. AB(): a(0){} C. AB(int aa=0) {a=aa;} D. AB(int aa) {}

(31)对于任一个类,用户所能定义的构造函数的个数至多为( )。 A. 0 B. 1 C. 2 D. 任意个

(32)对于任一个类,用户所能定义的析构函数的个数至多为( )。 A. 0 B. 1 C. 2 D. 任意个

(33)假定AB为一个类,则执行 “AB *px=new AB[n];”语句时将( )。 A. 动态分配一个对象数组 B. 动态分配一个对象 C. 静态分配一个数组 D. 静态分配一个对象

(34)设px是指向一个类对象的指针变量,则执行 “delete px;”语句时,将自动调用该类的( )。

13

A. 无参构造函数 B. 带参构造函数 C. 析构函数 D. 拷贝构造函数

(35)当一个类对象离开它的作用域时,系统自动调用该类的( )。

A. 无参构造函数 B. 带参构造函数 C. 拷贝构造函数 D. 析构函数 (36)假定一个类对象数组为A[n],当离开它定义的作用域时,系统自动调用该类析构函数的次数为( )。

A. 0 B. 1 C. n D. n-1

(37)假定AB为一个类,则执行 “AB a[10];”语句时调用该类无参构造函数的次数为( )。

A. 0 B. 1 C. 9 D. 10

(38)假定AB为一个类,则执行 “AB *px=new AB[n];”语句时调用该类无参构造函数的次数为( )。

A. n B. n-1 C. 1 D. 0

(39)一个类的静态成员变量所表示属性 ( )。

A. 是类的或对象的属性 B. 只是对象的属性 C. 只是类的属性 D. 类和友元的属性 (40)类的静态成员的访问控制( )。 A. 只允许被定义为private

B. 只允许被定义为private或protected C. 只允许被定义为public

D. 可允许被定义为private、protected或public (41)静态成员函数对类的成员变量访问( )。

A. 是不允许的 B. 只允许是静态成员变量

C. 只允许是非静态成员变量 D. 可允许是静态成员变量或非静态成员变量 (42)被非静态成员函数访问的类的成员变量( )。

A. 可以是非静态成员变量或静态成员变量 B. 不可能是类的静态成员变量

C. 只能是类的非静态成员变量 D. 只能是类的静态成员变量 (43)静态成员变量的初始化是在( )中进行的。 A. 构造函数 B. 任何成员函数 C. 所属类 D. 全局区

9.3 怎样定义私有成员?怎样定义公有成员?私有成员和公有成员有什么差别?

9.4 C++语言的类定义中,类的成员变量和成员函数分别描述了对象模型中的什么成分?

9.5 成员变量在定义时是否允许给出初始值?为什么?

9.6 构造函数的功能是什么?系统是在什么时候、以什么方式调用构造函数的? 9.7 析构函数的功能是什么?系统是在什么时候、以什么方式调用析构函数的?

14

9.8 构造函数是否可以重载?重载构造函数有什么意义?析构函数是否可以重载?

9.9 构造函数设计时应注意哪些事项?

9.10 什么样的类的析构函数可以设计为空?什么样的类的析构函数不可以设计为空?为什么?

9.11 C++语言中的构造函数和析构函数有返回值吗?你能解释其原因吗?

9.12 当在类定义体外实现成员函数时,为什么要在成员函数的返回类型后、成员函数名前加上“<类名>::”? 9.13 在编译完例3.1程序后,系统是否为各成员函数的参数分配了内存空间?为什么?

9.14 创建对象和定义变量有什么差别? 9.15 什么叫const对象? 9.16 怎样创建动态对象?

9.17 一个外部程序中的对象可以访问类中的私有成员吗?可以访问类中的公有成员吗?

9.18 写出对象调用其成员的语句形式。写出指向对象的指针调用其成员的语句形式。

9.19 一个非const成员函数可以修改类中的const成员变量吗?一个const成员函数可以修改类中的const成员变量吗? 9.20 什么叫重载?重载有什么意义?

9.21 什么叫子对象?整体——部分对象模式是怎样实现的?

9.22 什么叫外部类?什么叫内部类?什么样的类可以设计成内部类?

9.23 static成员变量和非static成员变量有什么差别?static成员函数和非static成员函数有什么差别?

9.24 若一个类的某个成员函数修饰为const,表示什么含义?若一个成员函数的某个参数修饰为const,表示什么含义?

9.25 在一个应用程序中,怎样进行static成员变量的初始化赋值?

9.26 类是创建对象的模板,一个程序中创建了许多对象,当这些对象都调用一个相同的成员函数时,系统是怎样区分当前是哪个对象调用的?

9.27 在开发一个应用系统时,应该用怎样的分析方法从现实世界中抽象出类? 9.28 类怎样体现了封装性?

9.29 以例3.16为例说明,类中的一个成员变量,是否可因为要求承担的任务太多而应该单独设计成一个类?

程序阅读和设计题:

9.30 阅读程序,给出运行结果:

(1)

#include \

15

class A {

private: int a,b; public :

A( ) { a=b=0;

cout<<\

}

A(int m) { a=b=m;

cout<<\ }

A(int m,int n) { a=m;b=n;

cout<<\ }

void print( ) { cout<<\ }

};

void main( ) { A a1,a2(10),a3(10,20); a1.print( ); a2.print( ); a3.print( ); }

2)

#include \class point {

private:

int x;

16

static int y; public:

point(int px=10) { x=px; y++;

} static int getpx(point a)

{ return(a.x); }

static int getpy(point b) { return(b.y); } void setx(int c)

{ x=c;

}

};

int point::y=0; void main() { point p[5];

for(int i=0;i<5;i++) p[i].setx(i); for (i=0;i<5;i++) { cout<

}

3)

#include \class sam {

int x; public:

17

void setx(int i) { x=i;

}

int putx() { return x; }

};

void main() {

sam *p; sam s[3];

for(int i=0;i<3;i++) s[i].setx(i+4); p=s;

for(i=0;i<3;i++)

cout<putx()<

4)

#include #include class A { char *a; public:

A(char *s) {

a=new char[strlen(s)+1]; strcpy(a,s); cout<

delete []a; cout<<\ }

};

void main() {

A x(\

18

A *y=new A(\ delete y; }

(5)

#include class A { int *a; public:

A(int x=0):a(new int(x)){} ~A() {delete a;}

int getA() {return *a;} void setA(int x) {*a=x;} };

void main() { A x1,x2(3); A *p=&x2; p->setA(x2.getA()+5);

x1.setA(15+x1.getA());

cout<

(6)

#include class A { int a; public:

A(int aa=0): a(aa) {cout<

void main() { A *p; A x[3]={1,2,3},y=4; cout<

delete []p; cout<

}

(7)

19

#include class A { int a,b; public:

A() {a=b=0;}

A(int aa, int bb) {a=aa; b=bb;} int Sum() {return a+b;} int* Mult() { int *p=new int(a*b); return p;

}

};

void main() { int *k;

A x(2,3), *p; p=new A(4,5);

cout<Sum()<<' '<<*(k=p->Mult())<

8)

#include class A {

int a[10]; int n; public:

A(int aa[], int nn): n(nn) {

for(int i=0; i

int Get(int i) {return a[i];} int SumA(int n) { int s=0;

for(int j=0; j

}

};

void main() {

int a[]={2,5,8,10,15,20}; A x(a,4);

20

}

A y(a,6);

for(int i=0; i<4; i++) d*=x.Get(i); cout<<\cout<<\

int d=1;

int f=y.SumA(5);

9.31 设计一个日期类,其输出格式是:“月/日/年”或“June 13,1993”,再编写一个测试程序,要求测试程序能实现两种输出格式的输出。 (提示:利用构造函数重载和输出成员函数重载。) 9.32 设计一个分数类。要求:

(1)分数类中包含的分数运算有:两个分数的加、减、乘、除运算。 (2)分数的输出格式是:分子/分母。

(3)编写一个测试程序进行测试。

(提示:分数类的成员变量应该有两个,即分子和分母。) 9.33 设计一个电视机类。要求:

(1)电视机的属性包括商品编号、商品型号、生产厂家、大小、重量、开/关状态。

(2)电视机的行为包括输出所有属性。 (3)要求商品编号自动生成。 (提示:利用static成员变量。)

9.34 编写一个基本账户类。成员变量包含有账号、储户姓名和存款余额;成员函数有存款和取款。并编写一个测试程序进行测试。

9.35 设计一个长方形类。成员变量包括长度和宽度;成员函数除包括计算周长和计算面积外,还包括用set方法来设置长方形的长度和宽度,以及用get方法来获得长方形的长度和宽度。最后,编写一个测试程序来测试所定义的长方形类能否实现预定的功能。

9.36 设计一个汽车性能类,其成员变量包括:颜色、品牌、车门、车灯、行驶速度;其方法包括:成员函数包括:打开车门、打开车灯、加速、减速等。最后,编写一个测试程序进行测试。

(提示:在成员函数中用输出成员函数名来表示该成员函数被调用。)

21

习题4

基本概念题: 9.1 填空题:

(1)一个类的成员函数也可以成为另一个类的友元函数,这时的友元说明必须在函数名前加上 的限定。

(2)重载运算符时,该运算符的__________、结合性以及操作符的个数不允许改变。

(3)一个单目运算符作为类的成员函数重载时有________个参数;如果作为独立函数重载,则有________个参数。

(4)一个双单目运算符作为类的成员函数重载时有________个参数;如果作为独立函数重载,则有________个参数。

(5)作为类的成员函数重载一个运算符时,参数表中只有一个参数,说明该运算符有________个操作数。

9.2 选择题:

(1) 当将一个类A或函数f()说明为另一个类B的友元后,类A或函数f()能够直接访问类B的( )。

A. 只能是公有成员 B. 只能是保护成员 C. 只能是除私有成员之外的任何成员 D. 具有任何权限的成员 (2)引入友元的主要目的是为了( )。

A. 增强数据安全性 B. 提高程序的可靠性 C. 提高程序的效率和灵活性 D. 保证类的封装性 (3)一个类的成员函数也可以成为另一个类的友元函数,这时的友元说明( )。 A. 需加上类域的限定 B. 不需加上类域的限定 C. 类域的限定可加可不加 D. 不需要任何限定 (4)在重载一个运算符时,其参数表中没有任何参数,这表明该运算符是( )。 A. 作为友元函数重载的1元运算符 B. 作为成员函数重载的1元运算符 C. 作为友元函数重载的2元运算符 D. 作为成员函数重载的2元运算符 (5)在成员函数中进行双目运算符重载时,其参数表中应带有( )个参数。 A. 0 B. 1 C. 2 D. 3

(6)双目运算符重载为普通函数时,其参数表中应带有( )个参数。 A. 0 B. 1 C. 2 D. 3

(7)如果表达式a+b中的“+”是作为成员函数重载的运算符,若采用运算符函数调用格式,则可表示为( )。

A. a.operator+(b) B. b.operator+(a) C. operator+(a,b) D. operator(a+b)

(8)如果表达式a==b中的“==”是作为普通函数重载的运算符,若采用运算符

22

函数调用格式,则可表示为( )。

A. a.operator==(b) B. b.operator==(a) C. operator==(a,b) D. operator==(b,a)

(9)如果表达式a++中的“++”是作为普通函数重载的运算符,若采用运算符函数调用格式,则可表示为( )。

A. a.operator++() B. operator++(a) C. operator++(a,1) D. operator++(1,a)

(10)如果表达式++a中的“++”是作为成员函数重载的运算符,若采用运算符函数调用格式,则可表示为( )。

A. a.operator++(1) B. operator++(a) C. operator++(a,1) D. a.operator++() (11)关于运算符重载,下列说法正确的是( )。 A. 重载时,运算符的优先级可以改变。 B. 重载时,运算符的结合性可以改变。 C. 重载时,运算符的功能可以改变。

D. 重载时,运算符的操作数个数可以改变。 (12)关于运算符重载,下列说法正确的是( )。 A. 所有的运算符都可以重载。

B. 通过重载,可以使运算符应用于自定义的数据类型。 C. 通过重载,可以创造原来没有的运算符。 D. 通过重载,可以改变运算符的优先级。 (13)假定K是一个类名,并有定义“K k; int j;”,已知K中重载了操作符 ( ),且语句“j=k(3);”和“k(5)=99;”都能顺利执行,说明该操作符函数的原形只可能是( )。

A. K operator ( ) (int); B. int operator ( )(int&); C. int & operator ( )(int); D. K &operator( )(int); (14)假定M是一个类名,且M中重载了操作符=,可以实现M对象间的连续赋值,如“m1=m2=m3;”。重载操作符=的函数原型最好是( )。

A. int operaotor=(M); B. int operator=(M&); C. M operator=(M&); D. M& operator=(M); (15)下面是重载双目运算符-的成员函数原形,其中最符合-原来含义的是( )。 A. Value Value::operator-(Value); B. Value Value::operator-(int); C. Value& Value::operator-(Value); D. Value& Value::operator-(Value&); 9.3 什么叫友元? 友元包括几种? 9.4 友元方法有什么优点和缺点?

9.5 友元类是否具有相互性?友元类是否具有传递性?友元类是否具有继承

23

性?

9.6 利用友元类或友元函数方法设计的程序是否可以提高程序运行效率?试举一例说明。

9.7 什么叫重载?什么叫运算符重载?运算符重载有什么意义?

9.8 哪些运算符可以重载?哪些运算符不可以重载?运算符重载有什么限制? 9.9 系统是怎样解释重载为成员函数的运算符的?系统是怎样解释重载为友元函数的运算符的?

9.10 哪些运算符最好应重载为成员函数形式? 哪些运算符最好应重载为友元函数形式?

9.11 输入运算符(<<)和输出运算符(>>)能重载为类的成员函数吗?为什么? 9.12 在C++语言中,当一个类没有设计赋值操作时,系统自动提供一个默认赋值操作,并把赋值操作重载为运算符(=)。分析为什么在例4.5的设计中,程序一定要重载赋值运算符?

9.13 分析例4.5的程序,说明Array类是怎样保证数组元素不越界的?控制数组元素越界对程序的可靠性有什么好处?

9.14 分析例4.6的程序,说明和C语言的字符串相比,String类有什么优点?

程序阅读和设计题:

9.15 阅读程序,给出运行结果:

#include \class sam {

private:

int x; sam() { }

void print() { }

void operator++() { }

x+=10;

cout<<\x=0;

public:

void operator--()

24

};

void main() { }

sam s; s.print(); ++s; s.print(); --s; s.print(); { }

x-=3;

9.16 在例4.2的基础上,增加判两个复数对象是否不相等的成员函数。

9.17 在例4.2的基础上,增加判两个复数对象是否不相等的成员函数。要求: (1)重载为类的成员函数。 (2)重载为类的友元函数。

9.18 完善例4.6的String类设计。要求: (1)逻辑操作再包括:逻辑不等于(=!)、逻辑小于(<)、逻辑小于等于(<=)、逻辑大于(>)、逻辑大于等于(>=)。

(2)字符串操作再包括:字符串连接(+)、字符串连接赋值(+=)。 (3)上述操作都要求运算符重载。

(4)设计一个可以测试各种运算符重载情况的测试程序,并进行测试。

9.19 设计一个矩阵类。要求: 矩阵类中重载加(+)、减(-)、乘(*)、赋值(=)和加赋值(+=)运算符。

25

习题5

基本概念题: 9.1 填空题:

(1)派生类的成员函数可以直接访问基类的 成员,不能直接访问基类的 ______成员。

(2)当保护继承时,基类的 成员在派生类中成为保护成员,派生类对象不能直接访问基类的 ____成员。

(3)在定义一个派生类时,使用__________关键字或者不显式地使用它则表示为__________继承。

(4)若多个基类及其派生类中都定义了同名成员函数,要访问相应函数时,就需要在函数名前加上______和类区分符。

(5)若要保证一个公共的基类在派生类中只产生一个基类子对象,则必须都以____________的方式直接继承它。

9.2 选择题:

(1)从一个基类派生出的各个类的对象之间( )。

A. 共享所有成员变量,每个对象还包含基类的所有属性 B. 共享部分成员变量,每个对象还包含基类的所有属性 C. 不共享任何成员变量,但每个对象还包含基类的所有属性 D. 共享部分成员变量和成员函数

(2)如果是类B在类A的基础上构造,那么,就称( )。 A. 类A为基类或父类,类B为超类或子类

B. 类A为基类、父类或超类,类B为派生类或子类 C. 类A为派生类,类B为基类

D. 类A为派生类或子类,类B为基类、父类或超类 (3)C++的继承性允许派生类继承基类的( )。

A. 部分特性,并允许增加新的特性或重定义基类的特性 B. 部分特性,但不允许增加新的特性或重定义基类的特性 C. 所有特性,并允许增加新的特性或重定义基类的特性 D. 所有特性,但不允许增加新的特性或重定义基类的特性 (4)派生类的成员函数可以直接访问基类的( )成员。

A. 所有 B. 公有和保护 C. 保护和私有 D. 私有 (5)对于公有继承,基类的公有和保护成员在派生类中将( )成员。 A. 全部变成公有 B. 全部变成保护

C. 全部变成私有 D. 仍然相应保持为公有和保护 (7)对于公有继承,基类中的私有成员在派生类中将 ( )。

A. 能够直接使用成员名访问 B. 能够通过成员运算符访问

26

C. 仍然是基类的私有成员 D. 变为派生类的私有成员

(8)当保护继承时,基类的( )在派生类中成为保护成员,在类作用域外不能够通过派生类的对象来直接访问该成员。

A. 任何成员 B.公有成员和保护成员 C. 保护成员和私有成员 D.私有成员

(9)在定义一个派生类时,若不使用保留字显式地规定采用何种继承方式,则默认为( )方式。

A. 私有继承 B. 非私有继承 C. 保护继承 D. 公有继承

(10)建立包含有类对象成员的派生类对象时,自动调用构造函数的执行顺序依次为( )的构造函数。

A. 自己所属类、对象成员所属类、基类 B. 对象成员所属类、基类、自己所属类 C. 基类、对象成员所属类、自己所属类 D. 基类、自己所属类、对象成员所属类

(11)当派生类中有和基类一样名字的成员时,一般来说,( )。

A. 将产生二义性 B. 派生类的同名成员将覆盖基类的成员 C. 是不能允许的 D. 基类的同名成员将覆盖派生类的成员 (12)C++中的虚基类机制可以保证:( )。 A. 限定基类只通过一条路径派生出派生类

B. 允许基类通过多条路径派生出派生类,派生类也就能多次继承该基类 C. 当一个类多次间接从基类派生后,派生类对象能保留多份间接基类的成员 D. 当一个类多次间接从基类派生后,其基类只被一次继承 (13)下列对派生类的描述中错误的说法是:( )。 A. 派生类至少有一个基类

B. 派生类可作为另一个派生类的基类

C. 派生类除了包含它直接定义的成员外,还包含其基类的成员 D. 派生类所继承的基类成员的访问权限保持不变 (14)派生类的对象对其基类中( )可直接访问。 A. 公有继承的公有成员 B. 公有继承的私有成员 C. 公有继承的保护成员 D. 私有继承的公有成员

9.3 什么叫基类?什么叫派生类?基类中保护成员的访问权限有什么意义? 9.4 公有继承、私有继承和保护继承方式下,基类中的私有成员、保护成员和公有成员,在派生类内和在类外两种情况下的访问权限是什么? 9.5 某个类的对象能直接调用该类的私有成员和保护成员吗? 9.6 什么叫派生类中的基类子对象?

9.7 从基类公有继承产生派生类时,基类中的构造函数和析构函数能被派生类继承吗?

27

9.8 怎样设计派生类的构造函数?

9.9 什么叫派生类覆盖基类的成员函数?派生类覆盖基类的成员函数有什么设计要求?

9.10 什么叫派生类重载基类的成员函数?派生类重载基类的成员函数有什么设计要求?

9.11 叙述基类和派生类的赋值兼容规则。赋值兼容规则有什么意义?

9.12 12.比较派生类对基类成员函数重载和派生类对基类成员函数覆盖两者的相同点和不同点。

9.13 什么叫多重继承?什么叫公共基类?举例说明多重继承中成员变量的二义性问题和成员函数的二义性问题。

9.14 什么叫虚基类?怎样解决多重继承中成员变量的二义性问题?怎样解决多重继承中成员函数的二义性问题?

9.15 下面的类中,哪些成员函数是重载?哪些成员函数是覆盖?

class Car { public: };

class SportsCar: public Car { public: };

SportsCar() {}

SportsCar(int s) {}

void f(int c) {}

void f(float d) {} Car() {}

void f(int c) {}

void d() {}

9.16 对于上题的Car类和SportsCar类,如果增加如下主函数,说明系统匹配各对象调用的成员函数分别是什么?

void main(void)

28

{ Car myCar;

SportsCar mySportsCar; int c = 5; float d = 5.0; myCar.f(c); mySportsCar.f(c); mySportsCar.f(d); mySportsCar.d();

}

程序阅读和设计题:

9.17 阅读程序,给出运行结果: (1)

#include \class A {

private: int a,b; public:

A(int i,int j) { a=i; b=j;

}

void move(int x,int y) { a+=x; b+=y; }

void show() { cout<

};

class B: private A {

private:

29

int x,y;

public:

B(int i,int j,int k,int l):A(i,j) { x=k; y=l;

}

void show() { cout<

void fun() { move(2,4);

}

void f1() { A::show(); }

};

void main() { A a1(10,10); a1.show(); B b1(5,5,6,6); b1.fun(); b1.show(); b1.f1(); }

2)

#include class Point { int x,y; public: Point(int x1=0, int y1=0) :x(x1), y(y1) { cout<<\

}

~Point() {

30

cout<<\

}

};

class Circle { Point center; //圆心位置

int radius; //半径

public: Circle(int cx,int cy, int r):center(cx,cy),radius(r) { cout<<\

}

~Circle() {cout<<\

};

void main() {

Circle c(3,4,5); }

3)

#include #include class Point { int x,y; public: Point(int x1=0, int y1=0) :x(x1), y(y1) { cout<<\

}

~Point() { cout<<\

}

};

class Text {

char text[100]; //文字内容 public:

Text(char * str) { strcpy(text,str); cout<<\ }

~Text() {cout<<\

};

31

class CircleWithText : public Point,public Text { public: };

void main() { }

CircleWithText cm(3,4,\

CircleWithText(int cx,int cy, char *msg): Point(cx,cy),Text(msg) { }

~CircleWithText() {cout<<\

cout<<\

(4)

#include class Date { public:

void SetDate(int y,int m,int d){ Year=y; Month=m; Day=d; } void PrintDate(){ cout<

Date(int y,int m,int d){SetDate(y,m,d);} protected:

int Year,Month,Day; };

class Time { public:

void SetTime(int h,int m,int s){ Houre=h; Minutes=m; Seconds=s;} void PrintTime()

{ cout<

Time(int h,int m,int s){SetTime(h,m,s);} protected:

int Houre, Minutes, Seconds; };

class Date_Time: public Date, public Time { public:

32

Date_Time( ):Date(),Time(){};

Date_Time(int y,int mo,int d,int h,int mi,int s): };

void main( ) {

Date_Time dt_a, dt_b(2002,10,1,6,0,0); dt_a.PrintDate_Time(); dt_b.SetTime(23,59,59); dt_b.PrintDate_Time(); dt_a.SetDate(2002,12,31); dt_a.PrintDate_Time(); }

Date(y,mo,d), Time(h,mi,s){}

void PrintDate_Time(){PrintDate();PrintTime();}

(5)

#include class Date { public:

Date(int y=2001,int m=1,int d=1){Year=y; Month=m; Day=d;} void PrintDate(){ cout<

int Year,Month,Day; };

class Time { public:

Time(int h=5,int m=30,int s=0){Houre=h; Minutes=m; Seconds=s;} void PrintTime()

{ cout<

int Houre, Minutes, Seconds; };

class Date_Time: public Date, public Time { public:

Date_Time( ){};

Date_Time(int y,int mo,int d,int h=0,int mi=0,int s=0):

33

Date(y,mo,d), Time(h,mi,s){}

void PrintDate_Time(){PrintDate();PrintTime();}

};

void main( ) {

Date_Time a, b(2002,10,1,6,20,0), c(2003,3,8,6,7); a.PrintDate_Time(); b.PrintDate_Time(); c.PrintDate_Time(); }

6)

#include class Base { public:

Base (int i,int j){ x0=i; y0=j;} void Move(int x,int y){ x0+=x; y0+=y;}

void Show(){ cout<<\private: int x0,y0; };

class Derived: private Base { public:

Derived(int i,int j,int m,int n):Base(i,j){ x=m; y=n;} void Show (){cout<<\ void Move1(){Move(2,3);} void Show1(){Base::Show();} private: int x,y; };

void main( ) {

Base b(1,2); b.Show();

34

Derived d(3,4,10,15); d.Move1(); d.Show(); d.Show1(); }

7)

#include class Point {

public:

void InitP(float x0=0, float y0=0) {X=x0;Y=y0;} void Move(float xf, float yf) {X+=xf;Y+=yf;} float GetX() {return X;} float GetY() {return Y;} private: float X,Y; };

class Rectangle: public Point {

public:

void InitR(float x, float y, float w, float h) { InitP(x,y);W=w;H=h;

}

void ZoomR(float k){W*=k,H*=k;} float GetH() {return H;} float GetW() {return W;} private: float W,H; };

void main() {

Rectangle rect;

rect.InitR(10,20,30,40);

cout<

<

35

cout<

cout<

9.18 设计一个点类,它仅包含两个属性:横坐标和纵坐标。通过继承点类再设计一个圆类,它除了有一个圆心,还有半径,还应该能够计算圆的周长和面积等。编写一个测试程序来测试所设计的类能否实现预定的功能。

9.19 设计一个动物类,它包含一些动物的属性,例如名称、大小、重量等,动物可以跑或走。然后设计一个鸟类,除了动物的基本属性外,它还有自己的羽毛、翅膀等,鸟除了跑或走外,它还可以飞翔。为了继承动物类的特性,鸟类应该继承动物类。编写一个测试程序来测试所设计的鸟类能否实现预定的功能。 9.20 先设计一个长方形类,再通过继承长方形类设计一个正方形类,正方形类中通过覆盖父类的成员函数得到一些新的功能。 9.21 先设计一个基本账户类,再通过继承基本账户类设计一个储蓄帐户类,储蓄帐户类中增加一个静态成员变量(年利率),并增加如下成员函数: (1)计算月利息:存款金额*年利率/12 (2)更改利率(静态方法):重新设置年利率

最后,编写一个测试程序来测试所设计的储蓄帐户类能否实现预定的功能。 9.22 先设计一个基本账户类,再通过继承基本账户类设计一个储蓄帐户类,储蓄帐户类中增加密码、地址、最小余额和利率等成员变量,并增加一些银行帐户经常用到的成员函数,要求:

(1)类中的成员函数具有输入、输出储户上述信息的功能。 (2)将账号设计成不可更改。 (3)修改密码时要提供原密码。

9.23 在阅读5.6.1节内容的基础上,进一步分析图书馆的图书和杂志管理和借阅方式,设计一个基本符合图书馆实际工作方式的图书和杂志借阅系统。

36

习题6

基本概念题:

9.1 什么叫运行时的多态性?动态绑定和运行时的多态性有什么关系? 9.2 什么叫虚函数?虚函数怎样实现运行时的多态性?

9.3 虚函数方法和派生类对基类成员函数覆盖方法有哪些相同之处和不同之处?

9.4 虚析构函数有什么作用?

9.5 什么叫抽象类?抽象类有什么用途? 9.6 怎样用纯虚函数方法设计抽象类? 9.7 空的虚函数和纯虚函数有什么区别? 9.8 虚函数怎样实现运行时的多态性? 9.9 纯虚函数可以实现运行时的多态性吗?

程序阅读和设计题:

9.10 阅读程序,给出运行结果:

#include class Base { public:

virtual void Set(int b){x=b;} virtual int Get(){ return x;} private: int x; };

class Derived: public Base { public:

void Set(int d){y = d;} int Get(){return y;} private: int y; };

void main( ) {

37

Base B_obj; Derived D_obj; Base *p=&B_obj; p->Set(100);

cout<<\ p=&D_obj; p->Set(200);

cout<<\ p->Base::Set(300);

cout<<\ p->Set(p->Get()+200);

cout<<\}

9.11 编写计算正方体、圆柱体、球体的表面积和体积的类。要求: (1)这三个类有一个公共的基类;

(2)这三个类计算正方体、圆柱体、球体的表面积和体积的成员函数名字相同; (3)按照运行时的多态性方法设计一个测试主函数,并进行测试。

9.12 设计一个异质链式堆栈类。要求堆栈中既可以保存int类型数据,也可以保存char类型数据。 (提示:(1)设计一个结点基类,再公有派生int类型的结点类和char类型的结点类;(2)主函数中用运行时的多态性方法构造链式堆栈。这样就可以构造出异质链式堆栈。)

9.13 设计一个异质链式队列类。要求队列中既可以保存int类型数据,也可以保

存char类型数据。

38

习题7

基本概念题:

9.1 常规方法是怎样设计处理方法相同、仅参数的数据类型不同的通用函数的? 9.2 什么叫参数多态性?什么叫模板?模板方法是怎样解决参数多态性问题的? 9.3 解释函数模板和模板函数。

9.4 解释类模板和模板类。类模板和模板类,哪个可以用来创建对象? 9.5 解释模板形参、模板实参和参数实例化。

9.6 写出函数模板的语句格式。说明函数模板的使用方法。 9.7 写出类模板的语句格式。说明类模板的使用方法。

程序设计题:

9.8 设计一个分数类模板。要求:

(1)分数类模板中包含的分数运算有:两个分数的加、减、乘、除运算。 (2)分数的输出格式是:分子/分母。

(3)测试程序中分子和分母既可以同时为int类型,也可以同时为float类型。 9.9 设计一个在三个数值中找出最大数值的函数模板。并设计一个测试程序进行测试。测试程序中三个数值既可以同时为int类型,也可以同时为float类型。 9.10 设计复数类模板。要求:

(1)复数类模板中包含的复数运算有:两个复数的加、减、乘、除运算,一个复数和一个实部数值的加、减、乘、除运算。 (2)设计一个测试程序进行测试。

9.11 设计单链表类模板。要求:

(1)单链表类模板中包含的单链表操作有:在单链表的某个位置插入一个数据元素,删除单链表某个位置中的数据元素。 (2)设计一个测试程序进行测试。

39

习题8

基本概念题:

9.1 什么是异常?举出程序中常见异常的例子。 9.2 简述异常处理的基本思想和方法?

9.3 对比传统异常处理的设计方法和本章讨论的异常处理的设计方法,说明本章讨论的异常处理有什么优点?

9.4 简述throw语句、try语句和catch语句的功能。 9.5 简述异常类的作用和设计方法。 9.6 当同时可能出现多个异常时, try-catch的不同排列顺序对异常处理有什么影响?

9.7 异常抛出和处理的方式有几种?在什么情况下,应该采用第一种方式?在什么情况下,应该采用第二种方式?

9.8 异常处理和程序的健壮性有什么关系?

9.9 C++异常处理的基本思想和基本方法是什么?

9.10 C++的throw-try-catch异常处理方法和C语言if语句的错误处理方法相比,有什么优点?

9.11 说明异常抛出和处理的两种方式。说明当异常类非空时,异常类在异常处理中有什么作用?

程序设计题:

9.12 设计一个考虑异常情况的模板堆栈类。并设计一个测试程序进行测试。 9.13 设计一个包括考虑异常情况的分数类和一个测试程序。 要求:(1)异常的抛出和处理采用第一种方式; (2)异常的抛出和处理采用第二种方式。

9.14 设计一个考虑邮件地址异常情况的邮件地址类。当用户输入的邮件地址不合法时,抛出异常。并设计一个包括异常处理的测试程序。

40

习题9

基本概念题:

9.1 什么叫流?什么叫流类?

9.2 什么叫文件? 广义文件可以是什么? 9.3 画出C++的类层次结构图。

9.4 ios类中状态标志的作用是什么?怎样设置状态标志?

9.5 ios类中文件流操作模式的作用是什么?怎样设置文件流的操作模式? 9.6 什么叫操作符?操作符有什么功能?怎样使用操作符? 9.7 写出文件操作的基本步骤。

9.8 什么叫可流类?把一个类设计成可流类有什么意义?

9.9 写出重载输入运算符“>>”和输出运算符“<<”的语法格式?为什么要求第一个参数是引用类型?

9.10 简述什么样的类称作可流类?

9.11 设计可流类时,为什么要把输入运算符“>>”和输出运算符“<<”重载为类的友元函数?

9.12 重载插入运算符<<时,其运算符函数的返回值类型应当是怎样的? 9.13 重载抽取运算符>>时,其运算符函数的返回值类型应当是怎样的?

程序阅读和设计题:

9.14 阅读程序,给出运行结果:

#include \#include \#include \void main() {

fstream file;

file.open(\if(!file) { }

char s[]=\for(int i=0;i

file.put(s[i]); file.seekg(5);

cout<<\abort();

41

}

char ch;

while(file.get(ch))

cout<

9.15 上机练习本章的例题程序。重点掌握文件的操作方法。

9.16 设计可流的数组类。即要求在数组类中重载输入运算符“>>”和输出运算符“<<”。

9.17 设计可流的字符串类。即要求在字符串类中重载输入运算符“>>”和输出运算符“<<”。

9.18 重新设计例9.9程序。要求把其中的学生结构体改成学生类。

42