《面向对象程序设计》课程期末复习资料
《面向对象程序设计》课程讲稿章节目录:
第一章、C++基础(16个知识点)
01 计算机求解问题的过程
02 编程的步骤
03 程序设计方法
04 程序设计基本概念
05 C++程序集成开发环境简介
06 C++程序实例
07 C++源程序的组成
08 C++源程序的组成元素
09 C++与C的主要差异 – 符号常量和标准输入输出流
10 C++与C的主要差异 – 内联函数
11 C++与C的主要差异 – 带默认形参值的函数
12 C++与C的主要差异 – 函数重载
13 C++与C的主要差异 – 动态内存分配和释放
14 C++与C的主要差异 – 动态内存分配和释放程序实例
15 C++与C的主要差异 – 引用和返回引用的函数
16 C++与C的主要差异 – 函数的引用调用
第二章、面向对象方法(27个知识点)
01 面向对象方法基本概念 – 对象、类、实例和消息
02 面向对象方法基本概念 – 封装、继承和多态
03 类的定义
04 构造函数
05 对象的定义和访问
06 对象的定义和访问程序实例
07 类成员的访问控制
08 类成员的访问控制程序实例
09 析构函数
10 拷贝构造函数
11 类声明和类实现的分离
12 类的常量成员
13 类的静态数据成员
14 类的静态成员函数
15 this指针
16 类的友元
17 类的对象成员 – 基本概念
18 类的对象成员 – 对象成员的声明、初始化和访问
19 自定义类的运算符重载概述
20 类成员函数形式的运算符重载
21 类友元形式的运算符重载
22 赋值运算符和下标运算符重载程序实例
23 类设计实例
24 面向对象方法程序实例 – 类和对象的基本定义、构造函数和析构函数
25 面向对象方法程序实例 – 静态成员和多文件结构
26 面向对象方法程序实例 – 友元和运算符重载
27 面向对象方法程序实例 – 对象成员
第三章、继承与多态(17个知识点)
01 继承概述
02 派生类定义
03 派生类构造函数和析构函数
04 派生类构造函数和析构函数程序实例
05 函数重定义和派生类的继承方式
06 多重继承下的派生类定义
07 多重继承中的二义性问题
08 虚拟继承和虚基类
09 类型兼容
10 多态性的概念和实现原理
11 虚函数
12 虚析构函数
13 纯虚函数和抽象类
14 继承与多态程序实例 – 派生类定义和函数重定义
15 继承与多态程序实例 – 多重继承
16 继承与多态程序实例 – 虚拟继承和虚函数
17 继承与多态程序实例 – 抽象类和纯虚函数
第四章、输入输出流(16个知识点)
01 输入输出流概述
02 输入输出流对象
03 输入输出流的插入和提取运算符
04 输入输出流的插入和提取运算符程序实例
05 输入输出流的put函数
06 输入输出流的get函数
07 输入输出流的getline函数
08 输入输出流的write函数
09 输入输出流的read函数
10 输入输出流的write、read函数程序实例
11 文件随机读写概述和相关函数
12 文件随机读写程序实例
13 自定义类型数据的标准输入输出和文本文件输入输出
14 自定义类型数据的二进制文件输入输出
15 输入输出流程序实例 – 输入输出流操作
16 输入输出流程序实例 – 插入运算符和提取运算符重载
第五章、模板(7个知识点)
01 函数模板的定义和使用
02 函数模板程序实例
03 类模板的定义
04 类模板的使用
05 类模板的静态成员
06 模板程序实例 – 函数模板
07 模板程序实例 – 类模板
一、客观部分:(单项选择、多项选择、不定项选择、判断)
(一)、选择部分
1、面向对象方法的基本观点是一切系统都是由( C )构成的。
A、结构 B、模块 C、对象 D、类
★考核知识点: 面向对象方法基本概念 – 对象、类、实例和消息
参见讲稿章节:2-01
附1.1.1(考核知识点解释):
面向对象方法的基本观点是一切系统都是由对象构成的,它们的相互作用、相互影响,构成了大千世界的各式各样系统。
2、下列关于主函数的叙述中正确的是( B )。
A、一个程序可以有多个主函数
B、程序从主函数开始执行
C、一个程序可以没有主函数
D、主函数是一个特殊的函数,因此其结构与其他函数不同
★考核知识点: C++源程序的组成
参见讲稿章节:1-07
附1.1.2(考核知识点解释)
一个C++程序一般由多个函数组成。这些函数可以是用户根据需要编写的自定义函数,也可以是直接使用系统提供的标准库函数。函数体用一对花括号“{”和“}”括起来。任何一个程序必须有且仅有一个主函数main,程序从主函数开始执行。
3、有关带默认参数的函数的描述正确的是( D )。
A、只能在函数定义时设置默认参数值
B、只能在函数声明时设置默认参数值
C、函数调用时,必须使用默认的参数值,不能给出新的实参值
D、设置默认参数时,应该设置最右边的若干个参数的默认值
★考核知识点: C++与C的主要差异 – 带默认形参值的函数
参见讲稿章节:1-11
附1.1.3(考核知识点解释)
在调用函数时,需要针对函数中的每一个形参给出对应的实参。C++中允许在函数定义或函数声明时给出默认的形参值。在调用函数时,对于有默认值的形参,如果没有给出相应的实参,则函数会自动使用默认形参值;如果给出相应的实参,则函数会优先使用传入的实参值。
默认形参值可以在两个位置指定:如果有函数声明,则应在函数声明处指定;否则,直接在函数定义中指定。默认形参值必须严格按照从右至左的顺序进行指定。
4、有关重载函数的描述正确的是( C )。
A、函数名相同的函数就是重载函数
B、函数名相同但返回值类型不同的函数就是重载函数
C、函数名相同但参数个数或类型不同的函数就是重载函数
D、函数功能相同的函数就是重载函数
★考核知识点: C++与C的主要差异 – 函数重载
参见讲稿章节:1-12
附1.1.4(考核知识点解释)
C++允许不同的函数具有相同的函数名,这就是函数重载。当调用一个函数时,除了要写出函数名,还要根据函数的形参列表传递实参值。
对于函数名相同的多个函数,要在调用时能够区分开到底要调用哪个函数,只能根据传递实参在数量或类型上的不同来进行判断。也就是说,函数名相同的函数形参列表不能完全一样,否则会因无法区分而报错。
5、假设堆内存分配均成功,则下面程序段完全正确的是( A )。
A、int *p=new int(3);cout<<*p;delete p;
B、int *p=new int[5]={1,2,3,4,5};for(int i=0;i<5;i++)cout<
( ){ }
⑤如果在类中声明了多个构造函数,这就是构造函数的重载。要求这些构造函数要有不同的参数表,系统自动调用构造函数时按照函数重载的规则选择其中的一个构造函数。
在对象的生存期结束时,有时也需要执行一些操作。这些工作就可以放在析构函数中。析构函数是一个特殊的由用户定义的公有成员函数,析构函数具有如下特征:
①析构函数名为:~<类名>,如~IntArray。
②构造函数无任何函数返回类型说明。
③析构函数无参数,所以不能被重载。
④如果在类声明中没有给出析构函数,系统会自动给出一个默认的析构函数:
~<类名>(){}
⑤
当对象的生命周期结束及用delete释放动态对象时,系统自动调用析构函数完成对象撤销前的处理。
12、在类的定义中,用于对类的数据成员进行初始化并执行其他内部管理操作的函数是( C )。
A、友元函数 B、虚函数 C、构造函数 D、析构函数
★考核知识点: 构造函数
参见讲稿章节:2-04
附1.1.12(考核知识点解释)
一个新的对象被创建时(通过对象声明语句或使用new运算符在堆区创建动态对象),属于该对象的构造函数被编译系统自动调用,完成该对象数据成员的初始化工作。
13、对于拷贝构造函数,正确的描述是( A )。
A、在C++语言中,如果不自定义类的拷贝构造函数,则每个类都有默认的拷贝构造函数
B、必须为每个类定义拷贝构造函数
C、如果要使用拷贝构造函数,则必须在类中先定义
D、当定义了类的构造函数时,如果要使用拷贝构造函数,则必须定义拷贝构造函数
★考核知识点: 拷贝构造函数
参见讲稿章节:2-10
附1.1.13(考核知识点解释)
拷贝构造函数有如下特征:
(1)拷贝构造函数名与类名相同,形参只有一个,是对象的引用,所以,不能重载拷贝构造函数。拷贝构造函数的原形为:
<类名>(<类名> &对象名);
(2)拷贝构造函数无任何函数返回类型说明。
(3)如果在类声明中没有给出拷贝构造函数,系统会自动给出一个默认的拷贝构造函数,该拷贝构造函数只进行对象数据成员间的对位拷贝,即所谓的“浅拷贝”。
(4)在某些情况下,用户必须在类定义中给出一个显式的拷贝构造函数,以实现用户指定的用一个对象初始化另一个对象的功能,即所谓的“深拷贝”。
(5)在以下3种情况下,系统会自动调用拷贝构造函数:
①当使用下面的声明语句用一个已存在的对象初始化一个新对象时,系统会自动调用拷贝构造函数:
<类名><新对象名>(<已存在对象名>);
或
<类名><新对象名>=<已存在对象名>;
②对象作为实参,在函数调用开始进行实参和形参结合时,会自动调用拷贝构造函数,完成由已知的实参对象初始化形参新对象的功能。
③如果函数的返回值是类的对象,在函数调用完成返回时,系统自动调用拷贝构造函数,用return后面的已知对象来初始化一个临时新对象(所创建的临时对象只在外部表达式范围内有效,表达式结束时,系统将自动调用析构函数撤销该临时对象)。
14、有关静态成员的描述错误的是( D )。
A、某个类的静态数据成员由该类的所有对象所共享
B、类的公有静态数据成员既可以用类的对象访问,也可以直接用作用域运算符“::”通过类名来访问
C、静态数据成员既可以是私有成员,也可以是公有成员
D、类中一旦定义了静态数据成员,就必须定义静态成员函数,以便对静态数据成员进行操作
★考核知识点: 类的静态数据成员
参见讲稿章节:2-13
附1.1.14(考核知识点解释)
在类的成员前如果加上关键字static,这种成员就是类的静态成员。类的静态成员包括静态数据成员和静态成员函数。类的静态成员的特点是:静态成员属于类,不属于任何对象。无论有多少对象或没有对象,静态成员都只有一份存于公用内存中,被该类的所有对象共享。
在类定义中的数据成员声明前加上关键字static,就使该数据成员成为静态数据成员。静态数据成员可以是public(公有)、private(私有)或protected(保护)的。在下面定义的Account类中,m_rate被声明为私有静态成员。
在类中声明的静态数据成员属于引用性说明,并不实际分配内存。在创建对象时,会为对象的数据成员分配存储空间。但由于静态数据成员不属于任何对象,所以在创建对象时也不会为该类的静态数据成员分配存储空间。所以,类设计者需要在类外对静态数据成员进行定义。静态数据成员的定义形式如下:
<类型><类名>::<静态数据成员名>[=<初值>];
类的静态数据成员不属于任何类,类的公有静态数据成员的一般访问形式是:
<类名>::<静态数据成员名>
也可以是:
<对象名>.<静态数据成员名>
或
<对象指针>-><静态数据成员名>
后两种访问方式中的“对象名”或“对象指针”只起到类名的作用,与具体对象无关。
如果成员函数被声明为static的,它就是静态成员函数。像静态成员数据一样,静态成员函数与具体对象无关。静态成员函数不能访问一般的数据成员,它只能访问静态数据成员,也只能调用其他的静态成员函数。
对类的静态成员函数的调用形式通常是:
<类名>::<静态成员函数调用>
可以用成员访问操作符点(.)和箭头(->)为一个类对象或指向类对象的指针调用,只是,这时候使用的只是对象的类型,与具体对象无关。
15、如果类A被说明成类B的友元,则( B )。
A、类A的成员函数不得访问类B的所有成员
B、类A的成员函数可以访问类B的所有成员
C、类A的成员即类B的成员
D、类B的成员即类A的成员
★考核知识点: 类的友元
参见讲稿章节:2-16
附1.1.15(考核知识点解释)
将一个类声明为另一个类的友类的语法形式为:
friend <友类名>;
或
friend class <友类名>;
将A类声明为B类的友类。声明后,A类的任何成员函数都有权访问B类中的任何成员,包括私有成员和保护成员。
16、下列关于this指针的说法,正确的是( D )。
A、this指针一定指向常量型数据
B、this指向的数据不可更改
C、静态成员函数中也可以访问this指针
D、this指针本身可直接作为成员函数的返回值
★考核知识点: this指针
参见讲稿章节:2-15
附1.1.16(考核知识点解释)
每个类成员函数都含有一个指向被调用对象的指针,这个指针被称为this指针。this指针是一个隐含于每一个非静态成员函数中的特殊指针,就是成员函数的一个类指针类型的形参。当对一个对象调用非静态成员函数时,编译程序先将该对象的地址传递给成员函数的this指针,以及完成其他的参数传递,然后再进入成员函数内部进行处理。在成员函数内部存取数据成员或调用其他成员函数时,都是通过this指针隐式地引用它所指向的对象的成员数据和成员函数。事实上,也可以通过this指针显式引用它所指向对象的成员数据和成员函数。
由于有了this指针的存在,使得类中相同的成员函数会根据this指针指向对象的不同而操作不同对象的数据成员。类的静态成员函数没有this指针。这是因为静态成员函数为类的所有对象所共有,不属于某一个对象。
一般情况下,this指针隐式使用就可以了。但某些情况下需要显式使用。下面是需要显式使用this指针的两种情况:(1)在类的非静态成员函数中返回类对象本身的时候,直接使用“return *this;”。(2)另外一种情况是当参数与成员变量名相同时。
17、派生类中的成员不能访问基类中的( A )。
A、私有成员 B、公有成员 C、保护成员 D、以上都可以
★考核知识点: 函数重定义和派生类的继承方式
参见讲稿章节:3-05
附1.1.17(考核知识点解释)
以公有方式继承时,基类的公有成员和保护成员的访问控制方式在派生类中保持不变,仍作为派生类的公有成员和保护成员,基类的私有成员在派生类中不能直接访问。
以私有方式继承时,基类的公有成员和保护成员在派生类中都作为私有成员,基类的私有成员在派生类中不能直接访问。
以保护方式继承时,基类的公有成员和保护成员在派生类中都作为保护成员,基类的私有成员在派生类中无法直接访问。
18、基类的( B )在私有继承时在派生类中为私有成员函数,在公有和保护继承时在派生类中为保护成员函数。
A、私有成员函数 B、保护成员函数
C、公有成员 D、保护数据成员
★考核知识点: 函数重定义和派生类的继承方式
参见讲稿章节:3-05
附1.1.18(考核知识点解释)
以公有方式继承时,基类的公有成员和保护成员的访问控制方式在派生类中保持不变,仍作为派生类的公有成员和保护成员,基类的私有成员在派生类中不能直接访问。
以私有方式继承时,基类的公有成员和保护成员在派生类中都作为私有成员,基类的私有成员在派生类中不能直接访问。
以保护方式继承时,基类的公有成员和保护成员在派生类中都作为保护成员,基类的私有成员在派生类中无法直接访问。
19、类型兼容是指在基类对象可以出现的地方,都可以使用公有派生类的对象,已知:
class BaseClass
{ //…};
class DerivedClass:public BaseClass
{ //…};
BaseClass b,*pb;
DerivedClass d,*pd;
下面不属于类型兼容的是( C )。
A、b=d; B、BaseClass &bb=d;
C、pd=&b; D、pb=&d;
★考核知识点:类型兼容
参见讲稿章节:3-09
附1.1.19(考核知识点解释)
类型兼容是指在基类对象可以出现的任何地方,都可以用公有派生类的对象来替代。类型兼容所指的是如下三种情况:
(1)派生类对象可以赋值给基类对象;
(2)派生类对象可以初始化基类的引用;
(3)基类指针可以指向派生类对象。
20、以下说法正确的是( C )。
A、重定义函数就是派生类的构造函数
B、重定义函数就是派生类的析构函数,要求同名
C、一个虚析构函数的版本被调用执行后,接着就要执行其基类版本
D、基类和派生类都分别给出了一个虚函数的不同版本
★考核知识点: 虚析构函数
参见讲稿章节:3-12
附1.1.20(考核知识点解释)
在调用派生类对象的析构函数后,会自动调用基类对象的析构函数来释放基类中定义的指针成员。
21、下列关于虚函数的说明中,正确的是( B )。
A、从虚基类继承的函数都是虚函数
B、虚函数不得是静态成员函数
C、只能通过指针或引用调用虚函数
D、抽象类中的成员函数都是虚函数
★考核知识点: 虚析构函数
参见讲稿章节:3-12
附1.1.21(考核知识点解释)
只有类的成员函数才能声明为虚函数。因为虚函数只适用于有继承关系的类对象,所以普通函数不能声明为虚函数。
静态成员函数不能是虚函数,因为静态成员函数不受限于某个对象。
内联函数不能是虚函数,因为内联函数不能在运行中确定其位置。即使虚函数放在类的内部定义,编译时,仍将其看作是非内联的。
构造函数不能是虚函数。因为构造时,对象还是一片未定型的空间。只有在构造完成后,对象才能成为一个类的名副其实的实例。
22、友元重载运算符obj1>obj2被C++编译器解释为( A )。
A、operator>(obj1,obj2) B、>(obj1,obj2)
C、obj1.operator>(obj2) D、obj2.operator>(obj1)
★考核知识点: 类友元形式的运算符重载
参见讲稿章节:2-21
附1.1.22(考核知识点解释)
友元函数“Complex operator-(Complex &c1,Complex &c2);”实现了减法运算符的重载。该函数函数名为operator-,有两个对象引用作为形参,返回值类型为对象类型。在主函数中可以用c1-c2的形式调用operator-()函数,相当于:operator-(c1, c2);
23、在表达式x+y*z中,+ 是作为成员函数重载的运算符,*是作为非成员函数重载的运算符。下列叙述中正确的是( C )。
A、operator+有两个参数,operator*有两个参数
B、operator+有两个参数,operator*有一个参数
C、operator+有一个参数,operator*有两个参数
D、operator+有一个参数,operator*有一个参数
★考核知识点: 类成员函数形式的运算符重载、类友元形式的运算符重载
参见讲稿章节:2-20、2-21
附1.1.23(考核知识点解释)
双目运算符计算时需要两个操作数,所以调用运算符重载函数时必须将要计算的两个操作数传递给函数。对于成员重载函数,必须是某个对象调用这个函数,而且将这个对象的地址传递给this指针,因此调用函数的这个对象就可以作为一个操作数传递给函数,另一个操作数作为实参传递给形参即可,这样成员重载函数只需要一个参数即可。相对的,友元函数是系统直接调用,所以两个操作数都要作为实参传递到函数中去,所以友元重载函数需要两个参数。
24、下列运算符中,( A )在C++中不能重载。
A、?: B、+ C、- D、<=
★考核知识点: 自定义类的运算符重载概述
参见讲稿章节:2-19
附1.1.24(考核知识点解释)
C++中不能重载的运算符只有5个:
. (成员访问运算符)
.* (成员指针访问运算符)
:: (域运算符)
?: (条件运算符)
sizeof (长度运算符)
25、下列运算符中,必须使用成员函数进行重载的是( B )。
A、== B、= C、>> D、++
★考核知识点: 自定义类的运算符重载概述
参见讲稿章节:2-19
附1.1.25(考核知识点解释)
C++规定,赋值运算符“=”,下标运算符“[]”,函数调用运算符“()”,类型转换运算符“()”,成员运算符“->”必须重载为成员函数。而插入运算符“<<”,提取运算符“>>”只能重载为非成员函数(友元函数)。
26、cout是I/O流库预定义的( B )。
A、类 B、对象 C、常量 D、包含文件
★考核知识点: 输入输出流对象
参见讲稿章节:4-02
附1.1.26(考核知识点解释)
从键盘输入、向屏幕输出称为标准输入/输出。为了实现标准输入/输出,C++预定义了4个标准流对象:cin、cout、cerr、clog,它们均包含于头文件iostream中。
27、4个预定义流对象为带缓冲的标准出错信息输出的是( D )。
A、cin B、cout C、cerr D、clog
★考核知识点: 输入输出流对象
参见讲稿章节:4-02
附1.1.27(考核知识点解释)
cin是istream类的对象,用于处理标准输入(键盘输入);cout是ostream类的对象,用于处理标准输出(屏幕输出);cerr和clog都是ostream类的对象,均用于处理出错信息标准输出。除了cerr不支持缓冲外,其他3个对象都支持缓冲输入/输出。
28、下面4个选项中,表示输入单个字符的是( B )。
A、cin B、cin.get() C、cin.put() D、cin.getline()
★考核知识点: 输入输出流的get函数
参见讲稿章节:4-06
附1.1.28(考核知识点解释)
istream类提供了用于输入单个字符的成员函数get(),istream的对象cin可以调用这个函数实现从键盘输入一个字符的操作。
cin调用get()有两种格式:
cin.get()
或
cin.get(ch)
其中,ch为字符型变量。
29、在C++中,打开一个文件,就是将该文件与( B )建立关联;关闭一个文件,就是取消这种关联。
A、类 B、流对象 C、对象 D、结构
★考核知识点: 输入输出流对象
参见讲稿章节:4-02
附1.1.29(考核知识点解释)
对文件进行输入/输出即读/写操作,必须先打开文件,使得文件与流对象建立关联,然后利用流对象调用文件流类的运算符或成员函数实现对文件的读写操作,操作完毕后关闭文件。
30、以下选项中,错误的是( C )。
A、fstream iofile; iofile.open("abc.txt", ios::in);
B、ofstream ofile; ofile.open("C:\vc\abc.txt", ios::binary);
C、cout.open("C:\vc\abc.txt", ios::binary);
D、ifstream ifile("C:\vc\abc.txt");
★考核知识点: 输入输出流对象
参见讲稿章节:4-02
附1.1.30(考核知识点解释)
打开文件使用文件流类的成员函数open(),当然在打开文件之前要先定义流对象,如:
ifstream infile;
infile.open("file1.txt");
或
ofstream outfile;
outfile.open("file2.txt");
首先定义文件流对象infile用于文件的输入(读)操作,然后文件流对象infile调用文件流类的成员函数open(),参数是要操作的磁盘文件名,open()函数实现的功能是打开文件file1.txt,并将流对象infile和文件建立关联。
也可将两条语句合并成一条语句,如:
ofstream outfile("file2.txt");
这样就是在定义时调用带参数的构造函数创建流对象outfile,参数为文件名file2.txt,这就是在构造函数中实现打开文件并将流对象outfile和文件建立关联的操作。
31、( C )使一个函数可以定义成对不同数据类型完成相同操作。
A、重载函数 B、模板函数 C、函数模板 D、递归函数
★考核知识点: 函数模板的定义和使用
参见讲稿章节:5-01
附1.1.31(考核知识点解释)
函数模板可以对不同类型的数据进行相同的处理,其作用与函数重载类似,但代码要简单得多。
32、函数模板的执行代码是在( D )时生成的。
A、执行函数 B、源程序中声明函数
C、源程序中定义函数 D、源程序中调用函数
★考核知识点: 函数模板的定义和使用
参见讲稿章节:5-01
附1.1.32(考核知识点解释)
函数模板需要实例化为模板函数后才能执行,即用实际的数据类型代替类型参数。实例化的函数模板称为模板函数。
函数模板的实例化是在函数调用时由编译器来完成的。当编译器遇到一个函数调用时,便根据实参表中实参的类型和已定义的函数模板生成一个模板函数,该模板函数的函数体与函数模板的函数体相同,而形参表中的类型则以实参表中的实际类型为依据。
(二)、判断部分
1、在C++程序中,主函数的函数名必须是main。 (√)
★考核知识点: C++源程序的组成
参见讲稿章节:1-07
附1.2.1(考核知识点解释)
一个C++程序一般由多个函数组成。这些函数可以是用户根据需要编写的自定义函数,也可以是直接使用系统提供的标准库函数。函数体用一对花括号“{”和“}”括起来。任何一个程序必须有且仅有一个主函数main,程序从主函数开始执行。
2、类中所提供的成员函数可以直接访问该类的私有成员。 (√)
★考核知识点: 类成员的访问控制
参见讲稿章节:2-07
附1.2.2(考核知识点解释)
公有成员:在public(公有) 区域内声明的成员是公有成员。公有成员在程序的任何地方都可以被访问。一般将公有成员限制在成员函数上,使其作为类与外界的接口,程序通过这种函数来操作该类的对象。
私有成员:在private(私有)区域内声明的成员是私有成员。私有成员只能被该类的成员函数或该类的友元访问。一般将类的数据成员和不希望外界知道其实现细节的成员函数声明为private
,程序必须通过类的公有成员函数才能间接地访问类的私有成员,从而实现了对类成员的封装。
保护成员:在protected(保护)区域内声明的成员是被保护的成员。被声明为protected(保护)访问级别的数据成员或成员函数只能在该类的内部或其派生类类体中使用。
3、类定义中的成员默认的访问权限是private。 (√)
★考核知识点: 类成员的访问控制
参见讲稿章节:2-07
附1.2.3(考核知识点解释)
如果没有指明是哪种访问级别,C++编译系统默认为私有(private)成员。
4、一个类中的保护成员和公有成员类似,在程序的任何地方都可以被访问。 (×)
★考核知识点: 类成员的访问控制
参见讲稿章节:2-07
附1.2.4(考核知识点解释)
公有成员:在public(公有) 区域内声明的成员是公有成员。公有成员在程序的任何地方都可以被访问。一般将公有成员限制在成员函数上,使其作为类与外界的接口,程序通过这种函数来操作该类的对象。
保护成员:在protected(保护)区域内声明的成员是被保护的成员。被声明为protected(保护)访问级别的数据成员或成员函数只能在该类的内部或其派生类类体中使用。
5、在一个类的成员函数中可以直接访问该类的私有成员变量,但不能直接访问该类的私有成员函数。 (×)
★考核知识点: 类成员的访问控制
参见讲稿章节:2-07
附1.2.5(考核知识点解释)
私有成员:在private(私有)区域内声明的成员是私有成员。私有成员只能被该类的成员函数或该类的友元访问。一般将类的数据成员和不希望外界知道其实现细节的成员函数声明为private,程序必须通过类的公有成员函数才能间接地访问类的私有成员,从而实现了对类成员的封装。
6、一个类只能有一个构造函数。 (×)
★考核知识点: 构造函数
参见讲稿章节:2-04
附1.2.6(考核知识点解释)
如果在类中声明了多个构造函数,这就是构造函数的重载。要求这些构造函数要有不同的参数表,系统自动调用构造函数时按照函数重载的规则选择其中的一个构造函数。
7、系统提供的缺省构造函数没有参数,所以自定义构造函数必须带有参数。 (×)
★考核知识点: 构造函数
参见讲稿章节:2-04
附1.2.7(考核知识点解释)
若在类中定义一个带参构造函数,则系统不再提供默认的无参构造函数;若创建对象时需要调用无参构造函数,就必须在类中定义一个无参构造函数。
8、一旦自定义了构造函数,系统便不再提供缺省的构造函数。 (√)
★考核知识点: 构造函数
参见讲稿章节:2-04
附1.2.8(考核知识点解释)
若在类中定义一个带参构造函数,则系统不再提供默认的无参构造函数;若创建对象时需要调用无参构造函数,就必须在类中定义一个无参构造函数。
9、一个类只能有一个析构函数。 (√)
★考核知识点: 析构函数
参见讲稿章节:2-09
附1.2.9(考核知识点解释)
析构函数无参数,所以不能被重载。
10、在一个类中声明了某个静态数据成员,并在类外给出其定义和初始化后,若未定义该类的对象,该静态数据成员则不存在。 (×)
★考核知识点: 类的静态数据成员
参见讲稿章节:2-13
附1.2.10(考核知识点解释)
在类的成员前如果加上关键字static,这种成员就是类的静态成员。类的静态成员包括静态数据成员和静态成员函数。类的静态成员的特点是:静态成员属于类,不属于任何对象。无论有多少对象或没有对象,静态成员都只有一份存于公用内存中,被该类的所有对象共享。
11、静态数据成员必须在类中进行定义和初始化。 (×)
★考核知识点: 类的静态数据成员
参见讲稿章节:2-13
附1.2.11(考核知识点解释)
在类中声明的静态数据成员属于引用性说明,并不实际分配内存。在创建对象时,会为对象的数据成员分配存储空间。但由于静态数据成员不属于任何对象,所以在创建对象时也不会为该类的静态数据成员分配存储空间。所以,类设计者需要在类外对静态数据成员进行定义。静态数据成员的定义形式如下:
<类型><类名>::<静态数据成员名>[=<初值>];
12、静态成员函数中不能访问非静态成员。 (√)
★考核知识点: 类的静态成员函数
参见讲稿章节:2-14
附1.2.12(考核知识点解释)
如果成员函数被声明为static的,它就是静态成员函数。像静态成员数据一样,静态成员函数与具体对象无关。静态成员函数不能访问一般的数据成员,它只能访问静态数据成员,也只能调用其他的静态成员函数。
13、类A的友元函数的函数体内能够访问类A中的任何成员。 (√)
★考核知识点: 类的友元
参见讲稿章节:2-16
附1.2.13(考核知识点解释)
将普通函数声明为类A的友元函数。声明后,普通函数有权访问类A中的任何成员,包括私有成员和保护成员。
14、如果类A是类B的友类,那么类A中的所有成员函数都可以访问类B中的所有成员。 (√)
★考核知识点: 类的友元
参见讲稿章节:2-16
附1.2.14(考核知识点解释)
将类A声明为类B的友类。声明后,类A的任何成员函数都有权访问类B中的任何成员,包括私有成员和保护成员。
15、派生类至少有一个基类。 (√)
★考核知识点: 继承概述
参见讲稿章节:3-01
附1.2.15(考核知识点解释)
在C++中,如果一个类C1通过继承已有类C而创建,则将C1称作派生类(也称做子类),将C称做基类(也称做父类)。派生类会继承基类中定义的所有属性和方法,另外也能够在派生类中定义派生类所特有的属性和方法。
16、在C++中,允许从一个类派生出任意多个类。(√)
★考核知识点: 继承概述
参见讲稿章节:3-01
附1.2.16(考核知识点解释)
如:以形状类为基类,可以派生出各种特定的几何形状,如圆形、四边形、三角形……,它们在具有形状类所定义的属性和行为的同时,还拥有各自的特性。
17、释放派生类的对象时,首先调用基类的析构函数,然后调用派生类的析构函数。 (×)
★考核知识点: 派生类构造函数和析构函数
参见讲稿章节:3-03
附1.2.17(考核知识点解释)
派生类构造函数的作用主要是对派生类中新添加的数据成员做初始化工作;在创建派生类对象、执行派生类构造函数时,系统会自动调用基类的构造函数来对基类中定义的数据成员做初始化。同样,派生类析构函数的作用主要是清除派生类中新添加的数据成员、释放它们所占据的系统资源;在销毁派生类对象、执行派生类析构函数时,系统会自动调用基类的析构函数来释放基类中数据成员所占据的系统资源。
当创建派生类对象时,先调用基类的构造函数,再调用派生类的构造函数;析构函数调用顺序总是与构造函数调用顺序相反。
18、在C++中,不允许某个类同时从多个类派生。(×)
★考核知识点: 多重继承下的派生类定义
参见讲稿章节:3-06
附1.2.18(考核知识点解释)
如果派生类是基于多个基类创建出来的,则称这个继承关系为多重继承。
19、已知:class Base1{//…};
class Base2{//…};
class Derived:public Base1, public Base2
{ Derived():Base2(),Base1(){}
//…
};
创建Derived类的对象时,先调用Base2的构造函数,然后调用Base1的构造函数,最后调用Derived的构造函数。 (×)
★考核知识点: 派生类构造函数和析构函数、多重继承下的派生类定义
参见讲稿章节:3-03、3-06
附1.2.19(考核知识点解释)
当创建派生类对象时,先调用基类的构造函数,再调用派生类的构造函数。
在多重继承中,各基类的构造顺序与派生类定义时基类表中各基类出现的顺序一致。而析构函数的调用顺序总是与构造函数调用顺序相反。
20、虚函数只有在有继承的情况时才会存在。 (√)
★考核知识点: 虚函数
参见讲稿章节:3-11
附1.2.20(考核知识点解释)
面向对象程序设计语言采用“后期绑定”,也可叫“动态绑定”技术,即当调用某个对象的函数时,应该被执行的程序代码会根据对象的具体类型在执行期被确定下来。这是实现多态性的技术保证。
想要实现多态,就要进行“后期绑定”,在C++中,实现“后期绑定”的机制是虚函数。
只有将派生类对象赋给基类对象引用或将派生类对象地址赋给基类对象指针时,才能够表现出多态性。
21、基类的指针或引用调用虚函数时采用后期绑定。 (√)
★考核知识点: 虚函数
参见讲稿章节:3-11
附1.2.21(考核知识点解释)
面向对象程序设计语言采用“后期绑定”,也可叫“动态绑定”技术,即当调用某个对象的函数时,应该被执行的程序代码会根据对象的具体类型在执行期被确定下来。这是实现多态性的技术保证。
想要实现多态,就要进行“后期绑定”,在C++中,实现“后期绑定”的机制是虚函数。
只有将派生类对象赋给基类对象引用或将派生类对象地址赋给基类对象指针时,才能够表现出多态性。
22、对虚函数的调用,系统都是采用动态联编。 (×)
★考核知识点: 虚函数
参见讲稿章节:3-11
附1.2.22(考核知识点解释)
只有将派生类对象赋给基类对象引用或将派生类对象地址赋给基类对象指针时,才能够表现出多态性。如果将派生类对象赋给基类对象,那么通过基类对象必然是调用基类中的函数。
23、抽象类虽然也是一种数据类型,但它不能建立对象,只能作为基类被其他类继承。(√)
★考核知识点: 纯虚函数和抽象类
参见讲稿章节:3-13
附1.2.23(考核知识点解释)
通常将不需要实例化的类定义成“抽象类”。抽象类不能实例化为对象,它的唯一用途是为其他类提供合适的基类,其他类可从它这里继承和(或)实现接口。
24、拥有纯虚函数的类称为抽象类,它不能用来定义对象。 (√)
★考核知识点: 纯虚函数和抽象类
参见讲稿章节:3-13
附1.2.24(考核知识点解释)
一个类如果是抽象类,则该类中至少有一个成员函数是纯虚函数,纯虚函数就是在声明时初始化为0的虚函数。
抽象类不能实例化为对象,它的唯一用途是为其他类提供合适的基类,其他类可从它这里继承和(或)实现接口。
25、由抽象基类继承得到的派生类肯定是具体类。 (×)
★考核知识点: 纯虚函数和抽象类
参见讲稿章节:3-13
附1.2.25(考核知识点解释)
如果某个类是从一个带有纯虚函数的类派生出来的,并且没有在该派生类中提供该纯虚函数的定义,则该虚函数在派生类中仍然是纯虚函数,因而该派生类也是一个抽象类。
26、对二元运算符采用成员函数重载时,只需要一个参数,而且该参数可以是内部类型。 (√)
★考核知识点: 类成员函数形式的运算符重载
参见讲稿章节:2-20
附1.2.26(考核知识点解释)
双目运算符计算时需要两个操作数,所以调用运算符重载函数时必须将要计算的两个操作数传递给函数。对于成员重载函数,必须是某个对象调用这个函数,而且将这个对象的地址传递给this指针,因此调用函数的这个对象就可以作为一个操作数传递给函数,另一个操作数作为实参传递给形参即可,这样成员重载函数只需要一个参数即可。
27、对一元运算符采用某个类的友元函数重载时需要一个参数,参数为该类的对象,不能是其他类型。 (√)
★考核知识点: 类友元形式的运算符重载
参见讲稿章节:2-21
附1.2.27(考核知识点解释)
使用成员函数重载单目运算符,不需要参数。因为只有一个操作数,而成员函数需要对象调用,该对象即为操作数传递给函数。使用友元函数重载单目运算符,需要一个参数,操作数作为实参传递给函数。
无论是成员重载还是友元重载,单目运算符重载时操作数类型必须是该类的对象。成员函数是对象调用,这个对象就是操作数。而对于友元函数,参数是操作数,但是参数也要求必须是该类型的对象,如果是其他类的对象或内部类型将没有意义,系统也不允许。
28、重载插入运算符“<<”必须采用成员重载。 (×)
★考核知识点: 自定义类型数据的标准输入输出和文本文件输入输出
参见讲稿章节:4-13
附1.2.28(考核知识点解释)
但是“>>”和“<<”不能对用户自定义类型的数据直接进行输入/输出。要使这两个运算符能够支持自定义类型数据的输入/输出,必须由编程人员对它们进行重载。重载的函数形式为:
istream& operator>>(istream&, 自定义类型&);
ostream& operator<<(ostream&, 自定义类型&);
运算符“>>”重载函数的第一个参数和返回值类型均为istream&(输入流对象的引用),第二个参数是自定义类型&(自定义类型数据的引用);运算符“<<”重载函数的第一个参数和返回值类型均为ostream&(输出流对象的引用),第二个参数是自定义类型&(自定义类型数据的引用)。
29、C++的输入/输出流库中,ios类是一个虚基类,istream类、ostream类以及streambuf类都是ios类的派生类。 (×)
★考核知识点: 输入输出流概述
参见讲稿章节:4-01
附1.2.29(考核知识点解释)
ios是一个抽象基类,提供一些对流状态、工作方式等设置的功能。ios类作为虚基类派生出istream类和ostream类。输入流类istream提供输入操作功能,输出流类ostream提供输出操作功能。输入/输出流类iostream是从istream类和ostream类通过多重继承而派生的类。iostream类将输入、输出功能融合在一起,因此编写程序时一般包含头文件iostream以实现输入/输出操作,因为在该头文件中含有对输入/输出流类的定义及输入/输出操作的相关信息。streambuf类和其他类没有继承关系,该类提供缓冲输入/输出的支持。
30、设inf是一个ifstream类的流对象,则inf.seekg(10,ios::beg);表示将文件指针从文件当前位置向后移动10个字节。 (×)
★考核知识点: 文件随机读写概述和相关函数
参见讲稿章节:4-11
附1.2.30(考核知识点解释)
seekg()函数和seekp()函数分别用于定位输入文件和输出文件的文件指针。它们的原型为:
isream& seekg(long offset,seek_dir origin=ios::beg);
osream& seekp(long offset,seek_dir origin=ios::beg);
seekg()函数的功能是将输入文件的文件指针从参照位置origin开始移动offset个字节,定位到新的位置。seekp()函数的功能是将输出文件的文件指针从参照位置origin开始移动offset个字节,定位到新的位置。
其中,参数offset是长整型,表示文件指针相对参照位置偏移的字节数。参数origin则为参照位置,seek_dir是系统定义的枚举类型,有以下3个枚举常量:
ios::beg文件首
ios::cur文件当前位置
ios::end文件尾
origin可以有以上3个取值,默认参数值为ios::beg。
二、主观部分:
(一)、程序题
1、写出下面程序的运行结果。
#include
using namespace std;
#define size 5
void get(int &n,int i)
{
n=i;
}
void print(int *n)
{
for(int i=0;i
using namespace std;
int nArray[] = {1, 2, 3, 4, 5};
int& Index(int nI)
{
return nArray[nI];
}
int main()
{
int nI;
for (nI = 0; nI < 5; nI++)
cout<
using namespace std;
class Sample
{
int x,y;
public:
Sample(){x=y=0;}
Sample(int a,int b){x=a;y=b;}
void disp()
{
cout<<"x="<
using namespace std;
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="<
using namespace std;
class Base
{
public:
void Who( ){cout<<"class Base"<Who();
p=&obj2;
p->Who();
p=&obj3;
p->Who();
obj2.Who();
obj3.Who();
return 0;
}
★考核知识点:函数重定义和派生类的继承方式
参见讲稿章节:3-05
参考答案:
class Base
class Base
class Base
class Derived1
class Derived2
6、写出下面程序的运行结果。
#include
using namespace std;
class Shape
{
public:
void Draw()
{
cout<<"Shape"<Draw();
c.Print();
sp2.Draw();
r.Print();
return 0;
}
★考核知识点:虚函数、纯虚函数和抽象类
参见讲稿章节:3-11、3-13
参考答案:
Shape
area:314
Shape
area:15
7、写出下面程序的运行结果。
#include
using namespace std;
class Sample;
Sample operator-(Sample &,Sample &);
Sample operator+(Sample &,Sample &);
class Sample
{
public:
Sample(){}
Sample(int i){n=i;}
friend Sample operator-(Sample &,Sample &);
friend Sample operator+(Sample &,Sample &);
void disp(){cout<<"n="<
using namespace std;
class Sample
{
public:
Sample(int i){n=i;}
void operator+=(int i){n+=i;}
void operator-=(int i){n-=i;}
void disp()
{
cout<<"n="<
#include
using namespace std;
int main()
{
ofstream file1;
file1.open("f1.dat");
file1<<123<>i>>j;
cout<<"i+j="<
using namespace std;
template
class add
{
T x, y;
public:
add(T a, T b)
{
x=a;
y=b;
}
T add1() { return x+y; }
};
int main()
{
add A(65, 120);
add B(13.6, 22.9);
cout<<"s1="<
using namespace std;
void swap(int &x, int &y)
{
int temp;
temp=x;
x=y;
y=temp;
}
int main()
{
int a,b;
cin>>a>>b;
swap(a, b);
cout<
#include
using namespace std;
class Person;
class TennisClub
{
public:
TennisClub(char *p,char *q)
{
strcpy(club,p);
strcpy(name,q);
}
void visit(Person);
private:
char club[24];
char name[24];
};
class Person
{
public:
Person(char *p,int y)
{
strcpy(name,p);
age=y;
}
friend void TennisClub::visit(Person x);
private:
char name[24];
int age;
};
void TennisClub::visit(Person x)
{
cout<<"姓名:"<
using namespace std;
class Student;
class Teacher
{
public:
void setScore(Student& s,double sc);
void setHour(Student& s,int h);
private:
long number;
char name[10]; };
class Student
{
public:
friend class Teacher;
double getScore() { return score; }
int getHour() { return semeHour; }
private:
long number;
char name[10];
double score;
int semeHour;
};
void Teacher::setScore(Student& s,double sc) {
s.score=sc; } // 可以直接访问Student的私有数据成员
void Teacher::setHour(Student& s,int h) {
s.semeHour=h; } // 可以直接访问Student的私有数据成员
int main() {
Teacher t;
Student s;
t.setScore(s,98.5);
t.setHour(s,5);
cout<
using namespace std;
class Point
{
public:
Point(double a,double b,double c){ X=a;Y=b;Z=c; }
double Getx(){return X;}
double Gety(){return Y;}
double Getz(){return Z;}
private:
double X,Y;
protected:
double Z;
};
class Line : public Point
{
public:
Line(double a ,double b,double c,double d):Point(a,b,c){ K=d; }
void show()
{
cout<
using namespace std;
class Furniture
{
public:
void SetWeight(int i){ m_weight =i; }
int GetWeight(){ return m_weight; }
void Move(int i){ cout<<"Move "<
using namespace std;
class Point
{
int X,Y;
public:
Point(int x=0, int y=0)
{ X=x; Y=y; Countp++; }
Point(Point &p)
{ X=p.X; Y=p.Y; Countp++; }
~Point()
{ Countp--; }
friend Point myfun(Point p1, Point p2, Point p3);
static int Countp;
void display(){cout<
#include
#include
using namespace std;
int main()
{
char str[80];
ifstream me("readme.txt");
if (!me)
{
cout<<"文件打开失败!"<
#include
using namespace std;
int main()
{
char ch[]="The end";
ofstream outstr("f7.txt", ios::app);
for(int i=0; i
#include
#include
using namespace std;
int main()
{
fstream file;
file.open("f7.txt", ios::in);
if(!file)
{
cout<<"Can not open f7.txt"<
#include
#include
using namespace std;
int main()
{
fstream infile, outfile;
infile.open("c:\file1.txt",ios::in);
if (!infile)
{
cout<<"file1.txt can't open.n";
abort();
}
outfile.open("c:\file2.txt",ios::out);
if(!outfile)
{
cout<<"file2.txt can't open.n";
abort();
}
char str[80]=" ";
while(!infile.eof())
{
infile.read(str,sizeof(str));
outfile.write(str, sizeof(str));
cout<
using namespace std;
template
class ff
{
Type a1, a2, a3;
public:
ff(Type b1, Type b2, Type b3)
{ a1=b1; a2=b2; a3=b3; }
Type sum()
{ return a1+a2+a3; }
};
int main()
{
ff x(12,13,14), y(16,17,18);
cout<
using namespace std;
int ComputeRectangleArea(int nL, int nW)
{
int nA = nL * nW;
return nA;
}
int main()
{
int nWidth, nLength, nArea;
cout<<"请输入长方形的长度和宽度(长宽都为整数):";
cin>>nLength>>nWidth;
nArea = ComputeRectangleArea(nLength, nWidth);
cout<<"长方形的面积为:"<
using namespace std;
int main()
{
double dA, dB, dR;
char cC;
cout<<"请输入四则运算式:";
cin>>dA>>cC>>dB; // 3.5+9.3
switch (cC)
{
case '+':
dR = dA + dB;
break;
case '-':
dR = dA - dB;
break;
case '*':
dR = dA * dB;
break;
case '/':
dR = dA / dB;
break;
default:
cout<<"输入四则运算式的格式不正确!"<
using namespace std;
int main()
{
int nInput, nS, nY, nR = 0;
cout<<"请输入一个十进制的正整数:";
cin>>nInput;
nS = nInput;
while (nS != 0)
{
nY = nS % 10;
nR = nR*10+nY;
nS = nS / 10;
}
cout<<"其倒序形式为:"<
using namespace std;
int main()
{
int nA, nB, nC; // nA^2+nB^2=nC^2
for (nC = 1; nC <= 20; nC++)
{
for (nB = 1; nB < nC; nB++)
{
for (nA = 1; nA <= nB; nA++)
{
if (nA*nA+nB*nB == nC*nC)
{
cout<
using namespace std;
void Display(char *s = "noname")
{
cout<
using namespace std;
void Display(char *s);
void Display();
int main()
{
Display("Li Xiaoming");
Display();
return 0;
}
void Display(char *s)
{
cout<
#include
using namespace std;
double ComputeDistance(int nX1, int nY1, int nX2, int nY2)
{
double dR;
dR = sqrt((double)(nX1-nX2)*(nX1-nX2)+(nY1-nY2)*(nY1-nY2));
cout<<"double ComputeDistance(int nX1, int nY1, int nX2, int nY2)函数被调用!"<
using namespace std;
int GetMax(int nA, int nB);
int GetMax(int nArray[], int nSize);
int main()
{
int nA[] = {5, 10, -6, 7, 25, 15};
cout< nB ? nA : nB;
}
int GetMax(int nArray[], int nSize)
{
int nMax = nArray[0], nI;
for (nI = 1; nI < nSize; nI++)
{
if (nMax < nArray[nI])
nMax = nArray[nI];
}
cout<<"int GetMax(int nArray[], int nSize)函数被调用!"<
using namespace std;
struct STU
{
char sNo[9]; // 用于存储学生学号(假设学生学号为位)
char sName[10]; // 用于存储学生姓名
int nScore[3]; // 用于存储学生三门课程的成绩
};
int main()
{
STU *pStu = NULL; // 表示指向一片无效内存
int nStuNum, nI, nJ, nTotal;
cout<<"请输入学生数量:";
cin>>nStuNum;
if (nStuNum <= 0)
{
cout<<"学生数量必须大于!"<>pStu[nI].sNo>>pStu[nI].sName;
for (nJ = 0; nJ < 3; nJ++)
{
cin>>pStu[nI].nScore[nJ];
}
}
for (nI = 0; nI < nStuNum; nI++)
{
nTotal = 0;
for (nJ = 0; nJ < 3; nJ++)
{
nTotal += pStu[nI].nScore[nJ];
}
cout<<"第"<>a>>b; // 输入3和4
swap(a, b); // 交换a和b的值
// 输出4和3
cout<
using namespace std;
void swap(int &nX, int &nY);
int main()
{
int nA, nB;
cout<<"请输入两个整数:";
cin>>nA>>nB; // 输入和
swap(nA, nB);
cout<<"交换后的值为:"<
using namespace std;
int nArray[] = {1, 2, 3, 4, 5};
int& Index(int nI);
int main()
{
cout<<"更改前的nArray[1]的值为:"<
using namespace std;
class Complex
{
public:
Complex(double dR, double dI);
void AddCom(Complex &c);
void Display();
private:
double m_dR;
double m_dI;
};
Complex::Complex(double dR, double dI)
{
m_dR = dR;
m_dI = dI;
}
void Complex::AddCom(Complex &c)
{
m_dR = m_dR+c.m_dR;
m_dI = m_dI+c.m_dI;
}
void Complex::Display()
{
if (m_dI >= 0)
cout<
using namespace std;
class String
{
public:
String(char *str);
int AddDgt(String &s);
private:
char m_str[100];
};
String::String(char *str)
{
strcpy(m_str, str);
}
int String::AddDgt(String &s)
{
int nCount = 0, nI;
for (nI = 0; nI < strlen(m_str); nI++)
{
if (m_str[nI] >= '0' && m_str[nI] <= '9')
{
nCount++;
}
}
for (nI = 0; nI < strlen(s.m_str); nI++)
{
if (s.m_str[nI] >= '0' && s.m_str[nI] <= '9')
{
nCount++;
}
}
return nCount;
}
int main()
{
String s1("1a2b3c4"), s2("d56ef78gh9");
cout<
using namespace std;
class AirPlane;
class Ship
{
public:
friend float CompareWeight(Ship &ship, AirPlane &airplane);
friend float TotalWeight(Ship &ship, AirPlane &airplane);
Ship(float fWeight);
private:
float m_fWeight;
};
Ship::Ship(float fWeight)
{
if (fWeight <= 0.0f)
{
cout<<"轮船重量必须大于0,因参数错误轮船重量将被初始化为1.0!"< 0.0f)
{
cout<<"轮船比飞机重!"<
#include
using namespace std;
class Student
{
public:
friend int Compare(Student &stu1, Student &stu2);
friend void DisplayScoreLevel(Student &stu);
bool SetData(string strName, int nScore); // 设置学生信息
void GetData(string &strName, int &nScore); // 获取学生信息
private:
string m_strName; // 保存学生姓名
int m_nScore; // 保存学生成绩
};
bool Student::SetData(string strName, int nScore)
{
if (nScore < 0 || nScore > 100)
{
cout<<"传入的成绩信息无效,成绩应在~100之间!"<>strName>>nScore;
if (!stu[nI].SetData(strName, nScore))
{
nI--;
}
}
nMin = nMax = 0;
for (nI = 1; nI < nStuNum; nI++)
{
stu[nMin].GetData(strName, nScore);
stu[nI].GetData(strName2, nScore2);
if (nScore > nScore2)
{
nMin = nI;
}
stu[nMax].GetData(strName, nScore);
if (nScore < nScore2)
{
nMax = nI;
}
}
stu[nMin].GetData(strName, nScore);
cout<<"成绩最低的学生信息:"<
using namespace std;
class Calculator
{
public:
int Add(int nOp1, int nOp2) { return nOp1+nOp2; }
int Sub(int nOp1, int nOp2) { return nOp1-nOp2; }
int Mul(int nOp1, int nOp2) { return nOp1*nOp2; }
bool Div(int nOp1, int nOp2, double &dR);
};
bool Calculator::Div(int nOp1, int nOp2, double &dR)
{
if (nOp2 == 0)
return false;
dR = (double)nOp1/nOp2;
return true;
}
class ECalculator : public Calculator
{
public:
int Jc(int nOp);
int Abs(int nOp) { return nOp>0?nOp:-nOp; }
};
int ECalculator::Jc(int nOp)
{
int nJc = 1, nI;
for (nI = 2; nI <= nOp; nI++)
{
nJc *= nI;
}
return nJc;
}
int main()
{
ECalculator e;
double dR;
cout<
#include
using namespace std;
class Triangle
{
public:
Triangle(double dA, double dB, double dC);
void Display();
double Area();
double operator+(Triangle &t);
private:
double m_dA, m_dB, m_dC;
};
Triangle::Triangle(double dA, double dB, double dC)
{
m_dA = dA;
m_dB = dB;
m_dC = dC;
}
void Triangle::Display()
{
cout<<"三角形的三条边长和面积分别为:"<
#include
using namespace std;
class Student;
bool operator<(Student &s1, Student &s2);
class Student
{
friend bool operator<(Student &s1, Student &s2);
public:
Student();
void SetData(string strName, int nScore[]);
void Display();
private:
string m_strName;
int m_nScore[3];
};
Student::Student()
{
m_strName = "noname";
m_nScore[0] = m_nScore[1] = m_nScore[2] = 0;
}
void Student::SetData(string strName, int nScore[])
{
int nI;
m_strName = strName;
for (nI = 0; nI < 3; nI++)
{
m_nScore[nI] = nScore[nI];
}
}
void Student::Display()
{
cout<<"学生的姓名、三门课程成绩和总成绩分别为:"
<>strName>>nScore[0]>>nScore[1]>>nScore[2];
stu[nI].SetData(strName, nScore);
}
for (nI = 0; nI < 3; nI++)
{
nK = nI;
for (nJ = nI+1; nJ < 3; nJ++)
{
if (stu[nJ] < stu[nK])
{
nK = nJ;
}
}
if (nI != nK)
{
stuTemp = stu[nI];
stu[nI] = stu[nK];
stu[nK] = stuTemp;
}
}
for (nI = 0; nI < 3; nI++)
stu[nI].Display();
return 0;
}
41、编写程序,实现Time类,在Time类中设计重载运算符函数使得如下运算成立:
Time t(23, 59, 59);
(t+1).Display(); // 输出0:0:0
t.Display(); // 输出23:59:59
★考核知识点:类成员函数形式的运算符重载
参见讲稿章节:2-20
参考答案:
#include
using namespace std;
class Time
{
public:
Time(int nHour, int nMinute, int nSecond);
Time operator+(int i);
void Display();
private:
int m_nHour, m_nMinute, m_nSecond;
};
Time::Time(int nHour, int nMinute, int nSecond)
{
m_nHour = nHour;
m_nMinute = nMinute;
m_nSecond = nSecond;
}
void Time::Display()
{
cout<
#include
using namespace std;
int main()
{
ofstream out;
ifstream in;
int nI, nJ, nK, nTemp, nSum;
out.open("fb.dat");
if (!out)
{
cout<<"文件打开失败!"<>nI;
nSum += nI;
}
in.close();
cout<<"前十项的和为:"<>”和“<<”,来实现类对象的输入与输出。
★考核知识点:自定义类型数据的标准输入输出和文本文件输入输出
参见讲稿章节:4-13
参考答案:
#include
using namespace std;
class Point;
istream& operator>>(istream&, Point&);
ostream& operator<<(ostream&, Point&);
class Point
{
friend istream& operator>>(istream&, Point&);
friend ostream& operator<<(ostream&, Point&);
private:
double m_dX, m_dY;
};
istream& operator>>(istream& in, Point& p)
{
in>>p.m_dX>>p.m_dY;
return in;
}
ostream& operator<<(ostream& out, Point& p)
{
out<<"("<>p;
cout<
using namespace std;
template T compmax(T x, T y)
{ return x>y?x:y; }
template T compmax(T arr[], int nSize)
{
T tmax = arr[0];
int nI;
for (nI = 1; nI < nSize; nI++)
if (tmax < arr[nI])
tmax = arr[nI];
return tmax;
}
char* compmax(char* cStr1, char* cStr2)
{
if (strcmp(cStr1, cStr2) > 0) return cStr1;
else return cStr2;
}
char* compmax(char* cStrArray[], int nSize)
{
int nI;
char* cMaxStr = cStrArray[0];
for (nI = 1; nI < nSize; nI++)
{
if (strcmp(cStrArray[nI], cMaxStr) > 0)
{ cMaxStr = cStrArray[nI]; }
}
return cMaxStr;
}
int main()
{
double dArr[] = {3.5, 7.2, 4.3, 6.8};
char* cStrArr[] = {"Beijing", "Shanghai", "Tianjin"};
cout<
using namespace std;
template
class Array
{
public:
Array(int nSize);
~Array();
T& operator[](int nIndex);
void Display();
private:
T *m_pArray;
int m_nSize;
};
template
Array::Array(int nSize)
{
m_nSize = nSize;
m_pArray = new T[nSize];
}
template
Array::~Array()
{
delete []m_pArray;
}
template
T& Array::operator [](int nIndex)
{
return m_pArray[nIndex];
}
template
void Array::Display()
{
int nI;
for (nI = 0; nI < m_nSize; nI++)
{
cout< nArray(10);
Array dArray(10);
Array cArray(10);
int nI;
for (nI = 0; nI < 10; nI++)
{
nArray[nI] = nI;
dArray[nI] = nI+9.8;
cArray[nI] = nI+'a';
}
nArray.Display();
dArray.Display();
cArray.Display();
return 0;
}