1、第2章 C+语言基础,本章要点 : C+的数据类型、运算符和表达式。 C+的控制结构。 面向对象程序设计方法。 类与对象。,2.1 C+语言概述,C+是在20世纪80年代早期由贝尔实验室设计的一种在C语言基础上增加了对面向对象程序设计的支持语言,是既适合于作为系统描述语言,也适合于编写应用软件的既面向对象又面向过程的一种混合型程序设计语言。,2.1.1 C+的发展历程,在C语言推出之前,操作系统等系统软件主要是用汇编语言编写的(如著名的UNIX操作系统)。 最初的C语言只是为描述和实现UNIX操作系统而提供的一种程序设计语言,1973年,贝尔实验室的K.Thompson和D.M.Ritchie
2、两人合作把UNIX操作系统的90以上的代码进行了重写,形成了UNIX V操作系统。 后来C又经过多次改进并在1978年后被移植到微型机上,C语言逐渐成为风靡全球的计算机程序设计语言。,2.1.1 C+的发展历程,上世纪80年代,美国AT&T贝尔实验室的Bjarne Stroustrup在C语言的基础上推出了C+(读作see plus plus)程序设计语言。 C+越来越受到重视并得到了广泛地应用,许多公司都为C+设计了自己的编译系统,如AT&T、Apple、Sun、Borland和Microsoft等,其中比较流行的有Borland公司的Borland C+和Microsoft公司的Visua
3、l C+。,2.1.1 C+的发展历程,同时,许多大学和科研机构也为C+编写了各种不同的类库,以方便C+的编程,其中Borland公司的OWL(Object Windows Library)和Microsoft公司的MFC(Microsoft Foundation Class)就是比较优秀的代表,尤其是Microsoft的MFC,得到了广泛的应用。,2.1.2 C+语言的特点,C+是一种通用程序设计语言,特别是面向系统程序设计,它具有以下特点: 是一个增强的C语言 支持数据抽象 支持面向对象的程序设计 支持通用型程序设计,2.2 一个简单的C+程序,2.2.1 一个C+例程,例2.1 利用VC
4、+ 6.0新建一个Win32 Console Application类型的工程ex21,添加C+ Source File文件后,输入以下代码: #include /包含头文件 void main( ) /main函数,程序入口 /程序体开始 cout“Hello,World!n“; /在屏幕输出字符串 cout“this is the first C+ program.“endl; /输出字符串和换行 int x=5; /定义整型变量x coutxendl; /输出x的值并换行 /程序体结束 编译、链接后,执行程序,输出结果如下: Hello,World! This is the first
5、C+ program. 5,2.2.2 C+程序的基本组成,一个C+程序往往是由预处理命令、函数、语句、变量和对象、输入与输出以及注释等几个基本部分组成的。 (1)预处理命令。 (2)函数。 (3)语句。 (4)变量和对象。 (5)输入与输出。 (6)注释。,2.2.3 C+程序的书写风格,C+既具有C语言的部分面向硬件特性,又拥有丰富的运算符,这导致了C+程序较其他语言难于理解。为了提高程序的可读性,C+程序的书写风格会起到很大的作用。因此,对于初学者来说,养成良好的代码书写习惯是非常重要和必要的。,2.2.3 C+程序的书写风格,2.2.3 C+程序的书写风格,1标识符命名 标识符是用来标
6、识变量名、函数名、数组名、类名、对象名、类型名、文件名等的有效字符序列。标识符命名的好坏也会影响程序的可读性,下面几个原则是标识符命名时所必须注意的: (1)合法性。C+规定标识符由大小写字母、数字字符(09)和下划线组成,且第一个字符必须是字母或下划线,任何标识符中都不能有空格、标点符号和其他字符。 (2)有效性。标识符的长度最好不要超过32个字符,因为有的编译系统只能识别前32个字符,即前32个字符相同的两个不同标识符被有的系统认为是同一个标识符。 (3)易读性。定义标识符时,若能做到“见名知义”就可以达到易读性的目的。,2.2.3 C+程序的书写风格,2缩进和注释 缩进是指程序在书写时不
7、要将程序的每一行都由第一列开始,而且在适当的地方加进一些空行或空格。它同注释一样,也是提高了程序的可读性。 注释的必要内容包括:源程序的总体注释、函数注释和少量必要的其他注释,注释应在编程过程中添加,不要等到程序开发完成后再补写。,2.3 数据类型、运算符和表达式,在C+中,任何数据在使用之前都要进行数据类型的定义,然后才能使用。,2.3.1 数据类型,C+的数据类型分为基本类型、构造类型和派生类型3种。,2.3.1 数据类型,1基本类型 基本类型是C+系统的内部数据类型,包括字符型(char)、整型(int)、单精度浮点型(float)以及空类型(void)等。表2-1是C+所提供的各种基本
8、数据类型、字宽及其值的范围,它们是根据ANSI(American National Standards Institute)标准制定的。,2.3.1 数据类型,2构造类型 C+中还提供了几种复合数据类型,这些复合数据类型包括数组、结构体、共用体、枚举、类和用户自定义类型。,2.3.1 数据类型,3派生类型 派生类型是将已有的数据类型定义成指针和引用,这些类型将在后续章节中陆续介绍。,2.3.2 常量与变量,根据程序中数据的可变性,数据可以分为常量和变量两大类。,2.3.2 常量与变量,1常量 在程序运行过程中,其值不能被改变的量称为常量。常量可分为不同的类型,如1、20、-6为整型常量,a为字
9、符型常量等。通过使用关键字const也可将一个变量定义为一个常量。,2.3.2 常量与变量,2变量 变量是指在程序执行过程中其值可以改变的量。变量的作用是存储程序中需要处理的数据,它可以放在程序中的任何位置上。但无论如何,在使用一个变量之前必须先定义这个变量。变量有3个基本要素:C+合法的变量名、变量类型和变量的数值。,2.3.3 运算符和表达式,和其他设计语言一样,C+描述运算的符号称为运算符,运算符的运算对象称为操作数。对一个操作数运算的运算符称为单目运算符;对两个操作数运算的运算符称为双目运算符;对3个操作数运算的运算符称为三目运算符。 C+的运算符同原来的C语言基本相同,增加了作用域运
10、算符()。,2.3.3 运算符和表达式,表达式是一个或多个运算符的组合,一个合法的C+表达式经过计算应有一个确定的值和类型,例如,35&2|84-!0。,2.4 指针,一个指针变量所存储的信息是一个对象在内存中的地址,通过指针,可以间接地访问对象。,2.4.1 指针的定义与使用,每一个指针都有一个相应的类型,该类型用以说明指针所指地址中存放的数据类型。 一个指针所占的内存空间大小与一个内存地址所占空间相等。也就是说,一个int型指针与一个double型指针占用同样大小的内存空间。在定义指针时,应在指针变量名前冠以星号“*”。例如: int a=5; int *p= /定义指针变量p,2.4.1
11、 指针的定义与使用,在使用指针变量前,一定要进行初始化或有确定的地址值,否则会产生错误。一个指针可以被一个具有相同类型的对象的左值初始化。为取得一个对象的左值必须引入一个新的运算符,这个新的运算符被称为取地址运算符,其符号是“&”。 一个指针变量还可以赋以零值,这表明它现在并不指向任何一个对象,作为指针变量的零通常写作NULL。这里还有另外一个指针类型:void *,它将使指针有能力指向任意类型的对象。,2.4.2 字符串指针,最常用的指针类型为char *,这是因为C+中,所有有关字符串的操作都是通过字符指针来完成的。所有字符串常量都是类型char *的对象。程序员可以说明一个char *类
12、型的变量并用一个字符串给它初始化。 例如,下面就是一个定义字符串指针并加以初始化的例子。 char *stName=“VC+ Program“;,2.4.3 指针与数组,数组中所有元素都是依次存储在内存单元中的,每个元素都有相应的地址。C+又规定数组名代表数组中第一个元素的地址,即数组的首地址。 例如,当有下列的数组定义时: int a10; 则a所表示的地址就是元素a0的地址。,2.4.3 指针与数组,若定义了指针: int *pa; 则pa=&a0和pa=a是等价的。 由于指针变量和数组的数组名在本质上是一样的,都表示地址值。因此指向数组的指针变量实际上也可像数组变量那样使用下标,而数组变
13、量又可像指针变量那样使用指针。例如:pai与*(pa+i)及ai是等价的,*(a+i)与*(pa+i)是等价的。,2.4.4 引用类型,引用是一个别名。当建立引用时,程序用另一个变量或对象的名字初始化它。对引用的改动,实际上是对目标的改动。引用类型是指对给定类型对象的引用。假如有一个变量a,想给它起个别名b,可以这样写:int &b=a,这样b就成为a的别名(引用),也可以说a、b代表同一变量,占有相同的内存空间。,2.5 C+的控制结构,C+提供了相应的语句如表达式语句、复合语句、选择语句和循环语句等,满足了结构化程序设计所需要的3种基本结构:顺序结构、选择结构和循环结构。,2.5.1 顺序
14、结构,系统按顺序执行程序中的所有语句,包括表达式语句、空语句和复合语句等。,2.5.2 选择结构,选择结构是用来判断所给定的条件是否满足,并根据判定的结果(真或假)决定哪些语句被执行。C+中构成选择结构的语句主要有条件语句(if)和开关语句(switch)。,1if else语句,if else语句根据不同的条件分别执行不同的语句序列,其语法形式如下: if(expression) statement1; /当expression为真时执行该语句 else statement2; /当expression为假时执行此语句 这里的if、else是C+的关键字,当if后面的表达式expressio
15、n为“真”时,将执行statement1。当expression为“假”时,statement2被执行。,2switch语句,switch语句用来测试某一个变量具有多个值时所执行的动作。switch语句的语法形式为: switch (expression) case constant1:statement1;break;case constant2:statement2;break;default:statement; 其中,switch、case、default都是关键字,当表达式的值与case中某个表达式的值相等时,就执行该case中“:”后面的所有语句。若case中所有表达式的值都不等于
16、switch表达式的值,则执行default:后面的语句,若default不存在,则跳出switch结构。,3条件运算符,条件运算符可以简化条件表达式的表示形式,其语法形式如下: expression1?expression2:expression3即表达式expression1为真时执行expression2的表达式,结果为假时执行表达式expression3。,2.5.3 循环结构,C+中提供了3种循环语句:while语句、dowhile语句和for语句。这些循环语句在许多情况下可以相互替换。,1while循环语句,while循环结构具有下列形式: while (expression)st
17、atement; 只要expression表达式的值为“真”,就重复执行statement语句。,2dowhile循环语句,dowhile循环语句总能保证循环体被执行一次,其形式如下: do Statement; while(expression); 注意,在dowhile循环结构中,while语句的括号内指定循环的条件,该句结尾处应以分号“;”结束。,3for循环语句,For语句通常用于处理具有固定长度的数据结构,例如数组等。下面是for循环语句的语法结构: for (expression1; expression2; expression3) statement; 其用法和执行过程同C语言
18、基本相同。,4break和continue语句,在C+程序中,若需要跳出循环结构或重新开始循环,就得使用break和continue语句,例如: while(i100) break; /跳出循环,执行cout语句statement1; cout “User Break!“;,4break和continue语句,continue语句与break语句不同,它并不中止整个循环的进行,而仅仅中止当前这一次循环的运行。例如: while(i100) continue; /跳出本次循环,继续下次循环statement1; cout “User Break!“;,2.6 函数,在结构化程序设计中,通常需要若
19、干个模块实现较复杂的功能,而每一个模块自成结构,用来解决一些子问题。这种模块化的结构设计思想能很好地发挥“团队”力量,在代码修改和重用上,极为方便和快捷。函数是结构化设计程序的基本单位。 函数定义的一般形式如下: 返回类型 函数名(形参列表) 函数声明部分;函数语句; ,2.6.1 函数的声明,定义一个函数就是为了以后的调用,但如果函数定义在后,而调用在前,就会产生编译错误。为了解决此类问题,必须将函数定义放在调用之前或在调用之前进行“函数的声明”。“函数的声明”消除了函数定义的位置的影响,也就是说,不管函数是在何处定义的,只要在调用前进行函数的声明就可以保证函数调用的合法性。例如,以下语句声
20、明了一个求最大值的函数: int max(int x,int y);,2.6.2 函数的参数传递,在调用函数时,大多数情况下,主调函数和被调函数之间会有参数传递的关系,因此,在程序中广泛使用的函数还是带参数的函数,在带参数的函数中,正确的参数传递是保障函数正常调用的不可或缺的部分。 C+中函数的参数传递有两种方式同C语言基本相同,一种是按值传递;另一种称为地址传递或引用传递。下面重点介绍一下C+语言的默认函数参数和引用传递。,2.7 文件与预处理,当程序中需要处理大量数据时,一方面由于数据量大不容易处理;另一方面因为内存中的信息在关机以后会全部丢失,所以试图将被修改的数据保存在内存中是根本不可
21、能的,必须借助文件将大量的信息长期保存下来。 另外,C+还允许使用预处理的方式对程序的编译环境进行扩充,预处理命令不属于C+语言,它只是为编译程序提供合适的编译环境。,2.7.1 预处理,C+提供的预处理命令主要有3种:宏定义命令、文件包含命令和条件编译命令。 这些命令在程序中都是以“#”开头,每一条预处理命令必须单独占一行;由于它不是C+语句,因此一般在结尾处没有分号“;”。,2.7.2 文件,文件是保存在存储介质上的一系列数据的集合。C+语言将文件看作是连续的字符数据顺序组成的。根据文件中数据的组成方式,可分为ASCII文件和二进制文件,ASCII文件又称为文本文件。 无论是文本文件还是二
22、进制文件,都需要用“文件指针”来操作。一个文件指针总是和一个文件相关联,当每一次打开文件时,文件指针指向文件的开始处,随着对文件的访问,文件指针不断地在文件中移动,并一直指向最新处理的字符位置。 文件操作一般分为:打开文件、读写文件、关闭文件等3种操作。 C+中文件的操作是通过使用fstream类来完成的。,2.8 类与对象,传统的结构化语句都是采用面向过程的方法来解决问题。在面向过程的程序设计方法中,代码和数据是分离的,因此程序的可维护性较差。面向对象(Object Oriented)的程序设计方法则是把数据及处理这些数据的函数封装到一个类中,类是C+的一种数据类型,而类的变量则称为对象。,
23、2.8.1 面向对象的程序设计方法,面向对象程序设计(Object-Oriented Programming,简称OOP)是以人们通常描述现实世界的方法来描述软件问题的,现实世界是由各种各样的对象构成的,比如计算机、汽车等,每个对象都有自己独特的属性和功能(方法),比如汽车的属性有汽车的颜色、型号等,其功能有前进、后退等。在软件世界里把对象的属性抽象为数据,把对象的功能抽象为函数,这样根据现实世界的对象就可以构造出软件世界的对象。,2.8.1 面向对象的程序设计方法,2.8.2 类的定义,类(class)是C+的精华,是进行封装和数据隐藏的工具。通过它把逻辑上相关的实体联系起来,并具备从外部对
24、这些实体进行访问的手段。和函数一样,应用类也是C+中模块化程序设计的手段之一。但是,函数是将逻辑上有关的语句和数据集合在一起,主要用于执行;而类则是逻辑上有关的函数及其数据的集合,它主要不是用于执行,而是提供所需要的资源。在使用一个类之前必须先定义类。,1类的定义,定义一个类的语法格式如下所示: class 类名:基类名 private:私有成员数据及函数;protected:保护成员数据及函数;public:公有成员数据及函数; 类的对象声明,2.8.3 对象,在C+中,对象是声明为类类型的一个数据项,是类的实际变量。程序员也可以定义类的变量。这个定义的类的变量在C+中就被称为对象。对象有时
25、也称为类的实例(instance)。由此可见,类是程序中的一个静态的概念,而对象则是程序中的一个动态概念。,2.8.3 对象,一个类定义后,就可以定义该类的对象。在C+中有两种方法可以定义类的对象: 第一种是在定义类的同时,直接定义类的对象,即在类定义的右大括号“”后直接写出属于该类的对象名表列,即: class 类名 成员数据表列;成员函数表列; 对象名表列; 还有一种是在定义好类后,再定义类的对象,其一般格式如下: 类名 对象1,对象2,对象3,;,2.8.4 内联函数,类的方法也可以声明和定义成内联函数。内联函数是指那些定义在类体内的成员函数,即该函数的函数体放在类体内。内联函数在调用时
26、不像一般的函数那样要转去执行被调用函数的函数体,执行完成后再返回调用函数中,然后执行其后面的语句;而是在调用函数处用内联函数体的代码来替换,这样将会提供更快的运行速度。因此内联函数主要是解决程序的运行效率问题。值得注意的是,内联函数一定要在调用之前定义,并且内联函数无法递归调用。,2.8.4 内联函数,在C+中可以使用下面两种格式定义类的内联函数: 当在函数的外部定义时,把关键字inline加在函数定义之前。例如,下面的程序段中定义的类angle的SetValue方法被定义成内联函数。 class angle /定义类 private:double value;public:void SetV
27、alue(double); ; inline void angleSetValue(double x)/定义内联函数 value=x; ,2.8.4 内联函数,把函数原型声明和方法的定义合并,放入类定义中。例如,下面的程序段在声明类angle的SetValue方法后,紧接着就定义该方法的具体实现。 class angle /定义类 private:double value; /定义私有数据成员public:void SetValue(double) /定义内联函数Value=x; ;,2.8.5 友元函数,类的重要特性之一是使数据封装与隐藏,这同时也给外部函数访问类中的私有和保护成员带来了不便
28、,为此,C+使用一个特殊的函数“友元函数”来解决这个问题。 “友元函数”必须在类中进行声明而在类外定义,声明时须在函数类型前面加上关键字friend。友元函数虽不是类的成员函数,但它可以访问类中的私有和保护类型的数据成员。,2.8.6 this指针,this指针是指向一个类的对象的地址、this是一种隐含指针,它隐含于每个类的成员函数之中,也就是说,每个成员函数都有一个this指针变量,this指针指向该成员函数所属的类的对象。当定义一个类的对象时,该对象的成员均含有由系统自动产生的指向当前对象的this指针。 成员函数访问类中成员变量的格式可以写成: this-成员变量;,2.8.6 thi
29、s指针,当一个对象调用成员函数时,该成员函数的this指针便指向这个对象。如果不同的对象调用同一个成员函数,C+编译器将根据成员函数的this指针所指向的不同对象类来确定应引用哪个对象的数据成员。也就是说,每个对象都有个地址,而this指针所指的就是这个地址。,2.8.6 this指针,和其他数据类型一样,程序中也可以定义指向类对象的指针,在定义了类的指针后还必须为其分配内存才能使用,类对象的指针定义及分配内存空间的一般格式为: 类名 *指针名=new 类名; 例如:下面的语句定义类CPoint的对象指针并为其分配内存: CPoint *Point1=new CPoint; 当通过类对象的指针
30、访问类的成员时,通常可以使用运算符“-”,例如,下面的例程中,主函数通过指向类对象的指针调用类的成员函数。,2.9 构造函数和析构函数,1构造函数 构造函数是一种特殊的成员函数,它主要用来为对象分配内存空间,对类的数据成员进行初始化并执行对象的其他内部管理操作。构造函数的特点是构造函数的名字和它所在的类名相同,当定义该类的对象时,构造函数完成对此对象的初始化。它可以接收参数并允许重载。当一个类含有多个构造函数时,编译程序为了确定调用哪一个构造函数,需要把对象中使用的参数和构造函数的参数表进行比较,这个过程与在普通的函数重载中进行选择的过程是一样的。,2.9 构造函数和析构函数,下面的程序中定义
31、了一个包含构造函数的类。 class student private:int num;float score;public:student(int NO, float S) /声明类student的构造函数num=NO;score=S; ;,2.9 构造函数和析构函数,2析构函数 析构函数也是类中的特殊成员函数,与定义它的类具有相同的名字,但要在前面加一个波浪号()。析构函数没有参数,也没有返回值,而且也不能重载,因此一个类中只能有一个析构函数。 析构函数执行与构造函数相反的操作,通常用于释放分配给对象的存储空间。当程序超出类对象的作用域时,或者当对一个类指针使用运算符delete时,系统将自
32、动调用析构函数。 和构造函数一样,如果在类的定义中不定义析构函数,编译系统将自动产生一个默认的析构函数,对于大多数类来说,默认的析构函数就能满足要求。如果在一个对象完成其操作之前还需要做一些内部处理,则应定义析构函数。,2.10 方法重载,重载是C+的一个重要特征,它包含函数重载和操作符重载。,2.10.1 函数重载,所谓函数重载是指同一个函数名可以对应着多个函数的实现。函数重载允许一个程序内声明多个名称相同的函数(这与C语言是不同的),这些函数可以完成不同的功能,并可以带有不同类型、不同数目的参数及返回值。使用函数重载可以减轻用户的记忆负担,并使程序的结构简单、易懂。 在C语言中,可以看到这
33、样的库函数:int abs( int x)、double fabs(double x)。这两个函数都是求某个数的绝对值,但不同的是,前者是求一个整数的绝对值,后者是求一个浮点数的绝对值。可见,由于函数参数类型的不同,要分别完成求整数和浮点数绝对值的任务,必须分别调用两个不同名称的函数abs()和fabs(),这无疑增加了记忆负担。 在C+语言中,可以给这两个函数起相同的名称,在函数调用时,系统会自动根据调用参数类型的不同来选择正确的函数版本,这就叫做函数的重载。,2.10.2 操作符重载,操作符重载的能力增强了C+语言的可扩充性,对操作符的重载是将C+语言中已有的操作符赋予新的功能,但与该操作
34、符的本来含义不冲突,使用时只需根据操作符出现的位置来判断其具体执行哪一种运算。 C+中单目运算、双目运算、动态内存管理运算符new和delete以及指针、引用等运算操作均可以重载,但要注意的是,由于单目运算操作只能有一个参数,因此重载+和-运算操作时,不可能区分是前置操作还是后置操作。 使用操作符重载时,必须用以下的方式来声明成员函数: 函数类型 operator # (形参表),2.11 继承,类是C+中进行数据封装的逻辑单位,C+还提供了一种继承机制,利用这种机制,用户可以通过增加、修改或替换给定类中的方法来对这个类进行扩充,以适应不同的应用要求。,2.11.1 类的继承性,类的继承性,又
35、叫类的派生性,是指从一个已经存在的类(基类)派生出一个新的类(派生类),派生类可以继承基类的部分或全部数据成员和成员函数,再增加新的数据成员和成员函数。MFC(微软基础类库)是微软公司为了方便Visual C+程序开发而设计的一套类库,Windows程序员一般都要在此类库的基础上进行开发,这无疑极大地减轻了工作量,因此类的派生性提高了程序代码的重用性。,2.11.1 类的继承性,2.11.2 多重继承,派生类的基类可以有一个,也可以有多个。如果只有一个基类,则这种继承方式叫做简单继承;如果基类名有多个,则这种继承方式称为多重继承。各个基类名之间用逗号隔开。 多重继承的格式与简单继承的格式基本相
36、同,其一般用法如下所示: class 派生类名:访问属性 基类名表 新增加的数据成员;新增加的成员函数; ;,2.12 多态性和虚拟函数,简单地讲,多态性就是一种实现“一种接口,多种方法”的技术,是面向对象程序设计的重要特性。,2.12.1 多态性,面向对象的语言多数都支持多态性,从本质上讲,多态性可以引用多个类的实例。 利用多态性,可以在基类和派生类中使用同样的函数名而定义不同的操作,从而实现“一个接口,多个方法”,这是一种在运行时出现的多态性,它通过派生类和虚拟函数来实现。虚拟函数是在基类中的成员函数前加上virtual,然后在派生类中再加以定义的函数。当用指向派生类的对象的基类指针对函数
37、进行访问时,系统将根据运行时指针所指向的实际对象来确定调用哪一个派生类的成员函数版本。当指针指向不同的对象时,执行的是虚拟函数的不同版本。,2.12.1 多态性,用多态性可以实现自上而下的设计方法。这是一种从全局出发,用类的层次结构来模拟客观世界的程序设计方法。通俗地说,多态性是指用一个相同的名字定义不同的函数,这些函数执行过程不同,但是有相似的操作,即用同样的接口访问不同的函数。运算符重载和函数重载就是一种多态性,这是编译时的多态性,也称静态多态性。而运行时的多态性则称为动态多态性。,2.12.2 虚拟函数,1基类的指针 在C+的类中,基类的指针可以指向派生类的对象,即基类的指针可以取派生类
38、对象的地址,但派生类的指针不可以指向基类的对象。,2.12.2 虚拟函数,2虚拟函数 虚拟函数就是在基类中与派生类重名的函数前,如student类中的display()函数前,加上关键字virtual,表示这个函数是虚拟函数。在派生类stud中的display()函数前可加virtual关键字也可以不加。这样基类的指针取派生类对象地址后,用这一指针调用display()函数,则调用的是派生类的display()函数,而非基类的display()函数。,2.12.3 虚拟析构函数,C+中不可以定义虚拟构造函数,但是可以定义虚拟析构函数。如果在基类和派生类中都定义了析构函数,而且希望程序能够根据需
39、要执行基类中的析构函数或者派生类中的析构函数,则必须把基类中的析构函数定义为虚拟析构函数,否则不能实现多态性。 虚拟析构函数以关键字virtual开头,这样定义后,基类中的析构函数及派生类的析构函数全部都是虚拟析构函数。虚拟析构函数的概念虽然十分简单,但它在面向对象程序设计中却是一种十分重要的技巧。一般的处理方法是,当在程序中定义了基类和派生类时,把基类中的析构函数设置为虚拟析构函数。,2.13 输入/输出流,C+中把数据之间的传输操作称作流。在C+中,流既可以表示数据从内存传送到某个载体或者设备中,即输出流;也可以表示数据从某个载体或者设备传送到内存缓冲区变量中,即输入流。广义地讲,可以把与数据传送有关系的事务叫做流。例如,可以把文件变量叫做流。有时候,流还可以代表要进行传送的数据的结构、属性和特性,用一个名字来表示,叫做流类;而用流代表输入设备和输出设备,叫做流的对象。 有关输入/输出的操作并没有在C+语言中定义,但它包含在C+的实现中,并作为C+的一个标准类库提供。在这里所讨论的I/O库指的是iostream库。任何一个使用iostream库的程序都必须包含头文件iostream.h。,