1、4.1 面向对象的思想v C+是一种面向对象的程序设计语言,使用它可以实现面向对象的程序设计。它与传统的结构化程序设计的联系与本质差别。二、结构化程序设计方法v结构化程序设计方法将解决问题的重点放在如何实结构化程序设计方法将解决问题的重点放在如何实现过程的细节方面,而把数据和对数据进行操作的现过程的细节方面,而把数据和对数据进行操作的函数截然分开,以数据结构为核心,围绕着功能实函数截然分开,以数据结构为核心,围绕着功能实现或操作流程来设计程序。这样设计出来的程序,现或操作流程来设计程序。这样设计出来的程序,其基本形式是主模块与若干子模块的组合,即一个其基本形式是主模块与若干子模块的组合,即一个
2、主函数(主函数(mainmain函数)和若干子函数。程序以函数为函数)和若干子函数。程序以函数为单位,函数之间以数据作为连接的纽带。正是由于单位,函数之间以数据作为连接的纽带。正是由于把数据和操作分开对待,因而有着方法本身无法克把数据和操作分开对待,因而有着方法本身无法克服的缺点。服的缺点。一、结构化程序设计方法v由于数据和操作代码(函数)的分离,一旦数据由于数据和操作代码(函数)的分离,一旦数据的格式或结构发生变化,相应的操作函数就得改的格式或结构发生变化,相应的操作函数就得改写,而且对于核心数据的访问往往也得不到有效写,而且对于核心数据的访问往往也得不到有效控制。同时,如果程序进行扩充或升
3、级改进,也控制。同时,如果程序进行扩充或升级改进,也需要大量修改函数。这样,程序开发的效率就难需要大量修改函数。这样,程序开发的效率就难以提高,大大限制了软件产业的发展。以提高,大大限制了软件产业的发展。第二种为第二种为OOPOOP面向对象程序设计程序框面向对象程序设计程序框架架(Object-Oriented Programming)(Object-Oriented Programming),它以类,它以类(class)(class)为核心,其程序主体为一批类定义的为核心,其程序主体为一批类定义的集合。集合。面向对象的程序设计面向对象的程序设计认为现实世界认为现实世界是由一系列彼此相关并且能
4、够相互通信是由一系列彼此相关并且能够相互通信的实体组成,的实体组成,这些实体就是面向对象方这些实体就是面向对象方法中的对象,而一些对象的共性的抽象法中的对象,而一些对象的共性的抽象描述,就是面向对象的核心描述,就是面向对象的核心类。类。v 四、面向对象程序设计v 在面向对象程序设计中,将对象作为构成软件系统的基本单元,并从相同类型的对象中抽象出一种新型的数据结构类。v对象是类的实例。类是一种区别于其它各种一般数据类型的特殊类型。类的成员中不仅包含有描述类对象属性的数据,还包含对这些数据进行处理的程序代码,称之为对象的行为(或操作)。对象将其属性和行为封装在一起,并将其内部大部分的实现细节隐藏起
5、来,仅通过一个可控的接口与外界交互。v 面向对象程序设计不仅实现了数据抽象,而且通过抽象出相关类的共性,而形成一般类(基类),并在此基础上,采用继承的方式,对一般类增添不同的特性而派生出多种特殊类(派生类),从而建立了类与类之间的多层结构关系,为软件复用提供有效的途径。v 面向对象程序设计支持多态性。多态性与继承性相结合,使不同结构的对象可以以各自不同的方式响应同一消息。v 软件系统的对象之间存在着依存关系,对象之间通过消息联系。面向对象程序设计中,消息表现为对象在其操作过程中对另一个对象的服务程序的调用。程序对象对象程序对象对象 对象对象 1 描述问题描述问题 解决问题解决问题 面向对象程序
6、设计方法面向对象程序设计方法 数据数据 算法算法 对象对象 n 数据数据 算法算法 第七章 类与对象v类(class)的概念是面向对象程序设计的核心概念。把数据和对象的操作和处理封装在一个程序模块中的方法,可以说是人们积几十年程序设计实践的经验总结。把程序以类的形式组织成若干模块,使其获得了最佳的结构特性,类的概念的引入使程序设计技术发生了革命性的转变。从结构程序设计(SP)中以函数作为程序的基本模块转变为面向对象程序设计(OOP)中,以类作为程序的基本模块,这一变化使程序设计技术出现了质的飞跃。数据抽象 封装 继承 多态 动态绑定面向对象方法的主要特点面向对象方法有三大支柱:封装性、继承性和
7、多态性。OOP程序设计要点:v (1)(1)有且仅有一个有且仅有一个mainmain函数,从它开始执行,函数,从它开始执行,它结束则整个程序结束。它结束则整个程序结束。v (2)(2)类以数据为中心,把相关的一批函数组类以数据为中心,把相关的一批函数组成为一体。类与类之间一方面通过封装而具有明确成为一体。类与类之间一方面通过封装而具有明确的独立性;另一方面,类与类之间又可通过成员、的独立性;另一方面,类与类之间又可通过成员、友元和参数的关系,通过继承和派生的关系,进行友元和参数的关系,通过继承和派生的关系,进行相互的通讯和联络,从而形成一个有机的整体。相互的通讯和联络,从而形成一个有机的整体。
8、v (3)(3)除上述主体部分外,如有必要,还可在除上述主体部分外,如有必要,还可在类之外加入全局量说明或全局函数定义等语法成分。类之外加入全局量说明或全局函数定义等语法成分。v (4)(4)可以从以下两个角度来看待类与对可以从以下两个角度来看待类与对象概念在编程中所起的作用。象概念在编程中所起的作用。v 第一第一,从,从程序的组织角度程序的组织角度看,看,C+C+通过通过classclass把数据以及对这些数据进行处理和运算的函把数据以及对这些数据进行处理和运算的函数封装为互相关联的程序模块,提高程序的可读数封装为互相关联的程序模块,提高程序的可读性、可维护性及可重用性。性、可维护性及可重用
9、性。v 第二第二,从,从数据类型的角度数据类型的角度看,看,C+C+通过通过classclass引入了抽象数据类型的概念。一个由数据成引入了抽象数据类型的概念。一个由数据成员及函数成员组成的一个类就是一种新的数据类员及函数成员组成的一个类就是一种新的数据类型。型。v通过类与对象而实现面向对象程序设计的三大通过类与对象而实现面向对象程序设计的三大特征:特征:封装性、继承性、多态性封装性、继承性、多态性。通过。通过抽象抽象对所对所要处理的问题进行划分、进行归类,通过要处理的问题进行划分、进行归类,通过类类(classclass)类型对所要处理的问题进行抽象描述,)类型对所要处理的问题进行抽象描述,
10、从而将逻辑上相关的数据与函数进行封装。封装从而将逻辑上相关的数据与函数进行封装。封装所进行的所进行的“信息隐蔽信息隐蔽”为的是减少对象间的联系,为的是减少对象间的联系,提高软件的模块化程度,增强代码的重用性。提高软件的模块化程度,增强代码的重用性。v通过类的继承,使新生成的所谓派生类可从其通过类的继承,使新生成的所谓派生类可从其基类那里得到已有的属性(数据)和行为特征基类那里得到已有的属性(数据)和行为特征(方法),从而可简化人们对事物的认识和描述。(方法),从而可简化人们对事物的认识和描述。面向对象语言通过继承机制很方便地实现了程序面向对象语言通过继承机制很方便地实现了程序代码的可重用问题。
11、代码的可重用问题。v多态性是通过对函数和运算符进行重载以及通多态性是通过对函数和运算符进行重载以及通过在基类及其派生类间对虚函数进行使用来具体过在基类及其派生类间对虚函数进行使用来具体体现的。多态性可使程序易于编制、易于阅读理体现的。多态性可使程序易于编制、易于阅读理解与维护。解与维护。v本章介绍类与对象的说明及其相关使用,下一本章介绍类与对象的说明及其相关使用,下一章将重点介绍继承性与多态性方面的内容。章将重点介绍继承性与多态性方面的内容。对象的数据和功能v对象表示现实世界中的实体。定义了周边的、与要解决的问题有关的概念或事物。对象有两种用途:v它们帮助理解现实世界v它们为计算机应用程序提供
12、实用基础对象(续)v每个对象都有它自己的特性或特征,描述它是什么或它做什么。交通监视应用程序中的车辆菜单鼠标和键盘人事文件有关某次考试的分数表时间复数将组织中的部门视为对象v每个部门的员工可对该部门的数据进行控制和操作SalesPersonnelAccounts不同的对象姓名:Jack年龄:28体重:65 kgs型号:Ferrari颜色:Red年份:1995动作:走路说话睡觉 动作:启动停止加速 v每个对象都有它自己的属性和操作,即它的静态特征和动态特征。属性是描述它的静态特征,而操作是描述其动态特征。如电视机有颜色、音量、频道等属性;还有一些操作,如切换频道、增减音量等。v 7.2.1 抽象
13、性v 抽象是指从具体的实例中抽取出共同的性质并加以描述的过程。比起面向过程的程序设计,面向对象程序设计更加强调抽象性。在面向对象方法中,抽象是通过对一个系统进行分析和认识,强调系统中某些本质的特性,而对系统进行的简化描述。对象的抽象类 v把具有相同特征和行为的对象归在一起就形成了类(Class)。它是一组具有相同属性和相同操作的对象集合,是对象的抽象,它抽象地描述了属于该类的全部对象的属性和操作。每个具体的对象只是该类的一个实例。类可以产生很多个对象,这些对象有不同的属性值。数据抽象 对 象 类 抽象数据类型 抽抽象象 抽抽象象 具具体体 具具体体 类是一组相似对象的抽象描述,它抽取了这些对象
14、的共性组成了一个共同的概念。抽象数据类型(Abstract Data Type,ADT)是一组相似的类的抽象,而一个类又是ADT的具体实现。数据抽象v用于将每个对象的特性和方法标识为与当前应用用于将每个对象的特性和方法标识为与当前应用程序有关将对象归为类,就是在执行一个问题的程序有关将对象归为类,就是在执行一个问题的数据抽象每个类的公共定义只存储一次,而不是数据抽象每个类的公共定义只存储一次,而不是对类的每个实例的公共定义都存储一次只需为每对类的每个实例的公共定义都存储一次只需为每个类编写一次方法,既可使类中的所有对象受益个类编写一次方法,既可使类中的所有对象受益于代码重用。于代码重用。类v拥
15、有相同特性、共同的行为和共同的关系的一组对象。v术语“类”是“对象的类”的缩略形式。例如:人类、动物类、过程类v每个对象称为它的类的实例对象和类抽象为多边形 类属性:顶点 边的颜色 填充的颜色 方法:绘制 抹去 移动多边形对象v对问题的抽象包括两个方面:数据抽象和行为抽象。数据抽象为程序员提供了对对象的属性和状态的描述,行为抽象则是对这些数据所需要的操作的抽象。v 抽象的过程是通过模块化来实现的,即通过分析将一个复杂的系统分解为若干个模块,每个模块是对整个系统结构的某一部分的一个自包含和完整的描述。同时,对模块中的细节部分进行信息隐藏,用户只能通过一个受保护的接口来访问模块中的数据。这个接口由
16、一些操作组成,定义了该模块的行为。v 看一个简单的例子。假设需要在计算机上实现一个绘制圆形的程序。通过对这个图形的分析,可以看出需要三个数据来描述该圆的位置和大小,即圆心的横、纵坐标以及圆的半径,这就是对该圆形的数据抽象。另外,该图形应该具有设置圆心坐标、设置半径大小、绘制圆形等功能,这就是对它的行为抽象。用C+语言可以将该图形描述如下:v圆形(circle):v数据抽象:vdouble x,y,r;v行为抽象:vsetx();sety();setr();draw();v抽象是面向对象方法的核心。王老师-姓名:王一凡-性别:男-年龄:33-职称:教授教师-姓名:string-性别:string
17、-年龄:int-职称:sting类对象图1-6类与对象的关系操作操作v 7.2.2 封装性v 封装是面向对象方法重要的原则和基本特性,其目的是有效地实现信息隐蔽和局部化。封装是指把对象的属性和操作结合在一起,组成一个独立的对象:其内部信息对外是隐蔽的,用户只能看到对象封装界面上的信息;不允许外界直接存取对象的属性,只能通过有限的接口与对象发生联系。只有对象内部的操作(方法)才能访问和修改该对象的属性。信息隐蔽和局部化封装 v所谓封装,就是将一个事物包装起来,使外界不了解它的详细内情。在面向对象方法中,把某些相关的代码和数据结合在一起,形成一个数据和操作的封装体,这个封装体向外提供一个可以控制的
18、接口,其内部大部分的实现细节则对外隐藏,从而达到对数据访问权限的合理控制。封装可以使得程序中各部分之间的相互影响达到最小,并且提高程序的安全性,简化代码的编写工作。封装(续)v如果适当地封装一些代码,就可以达到两个目的:如果适当地封装一些代码,就可以达到两个目的:构建一堵不可穿透的墙壁保护代码,使其不会构建一堵不可穿透的墙壁保护代码,使其不会因大家可能会犯的一些愚蠢小错误而受到意外因大家可能会犯的一些愚蠢小错误而受到意外破坏。破坏。还可分离错误,将其定位到一些小部分代码上,还可分离错误,将其定位到一些小部分代码上,从而更容易发现它们并予以纠正从而更容易发现它们并予以纠正封装是指软件的组成部分(
19、模块、子程序、方法等)应该互相独立,或者隐藏设计的细节。在传统的方法中,封装通常局限于将功能和数据分开封装;而在面向对象方法中,封装将功能和数据同时装入对象中。参看Student类的例子封 装class Student/Student类的声明public:/公有成员Student();/构造函数Student();/析构函数char*GetName();/查询姓名intGetAge();/查询年龄charGetSex();/查询姓名intGetNumber();/查询学号boolSetName(char*n);/设置姓名boolSetAge(int age);/设置年龄boolSetSex(c
20、har*s);/设置性别boolSetNumber(int num);/设置学号protected:/保护成员charm_strName20;/姓名,字符串数组intm_nAge;/年龄,整型charm_cSex;/性别,字符型intm_nNumber;/学号,整型;例:C+中类的声明Student类利用封装的特性,编写程序时,对于已有的成果,使用者不 必了解具体的实现细节,而只需要通过外部接口,依据特定的访 问原则,就可以实现这些现有的东西。在中,是利用类(class)的形式来实现封装的。以下以时钟的封装为例:class Clock /class 关键字;Clock 类名 /边界public
21、:/外部接口void SetDime(int NewH,int NewM,int NewS);/行为 代码成员void ShowTime();/行为 代码成员private:/特定的访问权限 int Hour,Minute,Second;/属性,数据成员;/边界v 7.2.3 继承性v 继承是软件复用的一种方式,通过继承,一个对象可以获得另一个对象的属性,并加入属于自己的一些特性。继承提供了创建新类的一种方法,即从现有类创建新类。新类继承了现有类的属性和行为,并通过对这些属性和行为进行扩充和修改,增添自己特有的一些性质。v 一个一般类可以派生出多个特殊类,不同的特殊类在一般类的基础上增加了不同
22、的特性。一个类也可以继承多个一般类的特性,这称之为多继承。v 继承是很重要的概念。继承支持多层分类的概念,使得一个个原来彼此孤立的类有效地组织起来,形成层次结构关系。倘若不使用多层分类的概念,对每个对象的清晰描述都要穷尽其特征,而采用继承的概念描述一个对象,只需在一般类特征的基础上加上该对象的一些专有特性即可。继承(续)v每个子类与它从其中派生的类具有共同的特性每个子类与它从其中派生的类具有共同的特性例如,汽车类中的所有车辆可能都有类似的特性:有车例如,汽车类中的所有车辆可能都有类似的特性:有车轮和发动机轮和发动机v子类可拥有它自己的特定特征子类可拥有它自己的特定特征例如,公共汽车有供人坐的座
23、位,而卡车拥有装货物的例如,公共汽车有供人坐的座位,而卡车拥有装货物的空间空间如果类与类之间有is-a(是一种)的关系,那么可以采用继承机制来表示。子类可以自动继承父类中的一些属性和行为,而不必再进行定义,从而实现了代码的复用。同时,继承也是产生新类的方法之一。继 承class People/People类的声明public:/公有成员People();/构造函数People();/析构函数char*GetName();/查询姓名intGetAge();/查询年龄boolSetName(char*n);/设置姓名boolSetAge(int age);/设置年龄private:/私有成员pro
24、tected:/保护成员charm_strName20;/姓名,字符串数组intm_nAge;/年龄,整型charm_cSex;/性别,字符型;类的声明举例People类class Student:public Peoplepublic:Student();/构造函数Student();/析构函数int GetNumber();/查询学号bool SetNumber(int n);/设置学号private:protected:intm_nNumber;/学号;类的声明举例Student类class Teacher:public People/Teacher类的声明public:/公有成员Tea
25、cher();/构造函数Teacher();/析构函数bool IsTeaching();/查询是否授课private:/私有成员protected:/保护成员boolm_bIsTeaching/是否授课;类的声明举例Teacher类v3、继承、继承v 分析问题,抽象得到数据和代码,使用类分析问题,抽象得到数据和代码,使用类进行封装,得到有机的整体,应该说只是面向对象进行封装,得到有机的整体,应该说只是面向对象程序设计的初步工作。程序设计的初步工作。一个程序员,如果领会了抽一个程序员,如果领会了抽象,问题就可以解决一半,如果懂得了封装,那就象,问题就可以解决一半,如果懂得了封装,那就可以起步进
26、行程序设计了。可以起步进行程序设计了。但是,对任何问题都从但是,对任何问题都从头开始描述,是不现实的。回想我们在前述关于人头开始描述,是不现实的。回想我们在前述关于人类认识问题的讨论,人们总是处于一个不断深入的类认识问题的讨论,人们总是处于一个不断深入的认识过程中,一个特定的问题,很可能前人已经进认识过程中,一个特定的问题,很可能前人已经进行过较为深入的讨论,这些结果怎么利用?行过较为深入的讨论,这些结果怎么利用?4、多态 继承,讨论的是类与类的层次关系;多态,则是考虑这种层次关系以及类自身成员函数之间的关系问题,是解决功能和行为的再抽象问题。多态,是指类中具有相似功能的不同函数使用同一名称来
27、实现的现象。这也是人类思维方式的一种直接模拟,在日常生活中也有类似的用法,比如“打球”这个“打”,就是一个多态现象,打篮球、打排球、打足球,其规则和实际“打”的操作相差甚远,只是功能相似,我们就统一使用“打”来表示,这实际上就是对多项运动的抽象。v多态性也是面向对象程序设计的重要特性之一。简单地说,多态性就是一个接口,多种方式。在基类中定义的属性和操作被派生类继承之后,可能具有不同的数据类型或表现出不同的行为,我们称之为多态性。也就是说,多态性表现为同一属性或操作在一般类及各特殊类中具有不同的语义。从同一基类派生出来的各个对象具有同一接口,因而能响应同一格式的信息,但不同类型的对象对该信息响应
28、的方式不同,导致产生完全不同的行为。在这里,消息一般是指对类的成员函数的调用,而不同的行为即用不同的函数实现。v 很明显,实现多态性的好处在于,为这类对象提供服务时,不必区分具体是哪种对象,只需发送相同的消息即可,而由各个对象去以适合自身的方式进行不同的响应。v 举一个简单的例子。编制绘图程序时,不同的图形其绘制的方式是不同的。可以声明一个基类“几何图形”,该类中定义一个“绘图”行为,并定义该类的派生类“直线”、“椭圆”、“多边形”等,这些类都继承了基类中的“绘图”行为。在基类的“绘图”行为中,由于图形类型尚未确定,所以并不明确定义如何绘制一个图形的方法,而是在各派生类中,根据具体需要对“绘图
29、”重新定义。这样,当对不同对象发出同一“绘图”命令时,各对象调用自己的“绘图”程序实现,绘制出不同的图形。编译时多态性是指在程序编译阶段即可确定下来的多态性,主要通过使用重载(Overloading)机制获得,重载机制包括函数重载和运算符重载两大类。举一个C+中的例子:int Abs(int x);double Abs(double x);coutAbs(-4)endl;/调用int AbscoutAbs(3.2)endl;/调用double Abs运行时多态性是指必须等到程序动态运行时才可确定的多态性,主要通过继承结合动态绑定获得。动态绑定也称晚绑定,它也是面向对象的重要特点之一。动态绑定的
30、使用可以提高程序的可用性和可扩展性。三、C+语言C与C+的比较C+中的数据类型C+程序框架类和对象类的声明、实现、继承、多态性举例C+语言与C语言最显著的区别是它的面向对象的特征,引进了类与对象的概念。类封装了一组数据结构和作用于该数据结构的一组方法,下面对C+语言的介绍将着重围绕类来进行介绍。第七章 类 类的引入类的引入 类的具体语法形式类的具体语法形式 构造函数和析构函数构造函数和析构函数 this this指针、静态成员和常量成员指针、静态成员和常量成员 友元和嵌套类友元和嵌套类 对象数组和指针间的关系对象数组和指针间的关系class 类名public:公有数据和函数protected:
31、受保护数据和函数private:私有数据和函数;类的声明注意要有分号 class private:;public:;7.2 类和对象的说明 v 1.1.通过如下一般方式来自定义类通过如下一般方式来自定义类(class)(class)类型:类型:vv class class v private:private:v ;v public:public:v ;v v protected:protected:v;v ;v ;class People/People类的声明public:/公有成员People();/构造函数People(char*name,int age,char sex);People(
32、);/析构函数char*GetName();/查询姓名intGetAge();/查询年龄charGetSex();/查询性别boolSetName(char*n);/设置姓名boolSetAge(int age);/设置年龄boolSetSex(char sex);/设置性别private:/私有成员protected:/保护成员charm_strName20;/姓名,字符串数组intm_nAge;/年龄,整型charm_cSex;/性别,字符型;类的声明举例People类类的定义格式一般分为两个部分:)、说明部分:用来说明该类中的成员(数据成员、成员函数),告诉使用者“干什么”。)、实现部分
33、:用来定义成员函数。该函数用来对数据成员进行操作。告诉使用者“怎么干”。其中,是类中定义的实现部分,这部分包含了所有在类中说明函数的定义。如果一个成员函数在类中定义了,实现部分不出现。如果所有的成员函数都在类体内定义,则实现部分可以省略。定义类的几点需要注意:v (1)若所说明的类有基类的话,则“:”部分不可缺省。v (2)private关键字后列出本类的私有成员;public后列出本类的公有成员;而protected后列出本类的保护成员。v (3)成员又区分为数据成员与函数成员两种。数据成员代表该类对象含有的数据(描述属性);而函数成员则代表如何对该类对象所含数据进行操作的代码(描述对该类对
34、象的处理方法)。v 函数成员既可放于类定义体的花括号之函数成员既可放于类定义体的花括号之中,也可按类外定义方式放于之外(但要求类体内中,也可按类外定义方式放于之外(但要求类体内必须有其函数原型,且类体外函数说明的前面必须必须有其函数原型,且类体外函数说明的前面必须用用“:”:”来限定)。凡在类体中定义的函数来限定)。凡在类体中定义的函数成员均隐含为内联函数。成员均隐含为内联函数。定义类的几点需要注意:v (4)以friend说明的友元并不是本类的成员,被说明为本类友元的那些函数享有本类成员函数的“权利”-可以访问本类的私有成员。v (5)private、public、protected以及fr
35、iend“说明段”的顺序可以任意;每一类型的“说明段”均可以出现多次,或者一次也不出现。若紧随若紧随左花括号后的第一个左花括号后的第一个“说明段说明段”为为privateprivate的话,则的话,则该该privateprivate关键字可以省略。关键字可以省略。v v类的成员函数用于对数据成员处理,又称为类的成员函数用于对数据成员处理,又称为“方法方法”。程序中通过类的成员函数来访问其。程序中通过类的成员函数来访问其内部的数据成员。成员函数是类与外部程序之内部的数据成员。成员函数是类与外部程序之间的接口。在类的声明体中只需声明成员函数间的接口。在类的声明体中只需声明成员函数的原型,成员函数的
36、具体实现可放在类外定义。的原型,成员函数的具体实现可放在类外定义。成员表:若干成员序列。成员:数据成员和函数成员。数据成员:变量或对象说明语句。函数成员:函数说明(定义)语句。除该类的成员函数外,谁都不得访问程序中所有函数都可访问可以省去类的实例也就是所谓的对象:stack sta1;stack*pstack=new stack;堆栈的类版本:class stack private:char v100;char*p;public:void push(char c)/char pop()/;v通常采用下面的形式定义成员函数:v :()vv vv下面的例子就是一个简单的类的说明。v【例4-1】类的
37、声明例题。vclass myclassvprivate:vint a;vpublic:vvoid set_a(int num);vint get_a();v;vvoid myclass:set_a(int num)a=num;int myclass:get_a()return a;在一个系统中,每一个对象均属于某个类,类是对象的属性和操作的定义模板,而实例是某个具体的对象。v 4.5.2 4.5.2 类成员的访问控制类成员的访问控制v 在缺省情况下,类中说明的所有函数和在缺省情况下,类中说明的所有函数和变量都为这个类所私有,也就是说,这些函数变量都为这个类所私有,也就是说,这些函数和变量只能在
38、该类成员函数的实现中被访问。和变量只能在该类成员函数的实现中被访问。为了说明某些成员是公有成员(可以被其它类为了说明某些成员是公有成员(可以被其它类的成员访问的成员称为公有成员),必须使用的成员访问的成员称为公有成员),必须使用关键字关键字publicpublic,并在后面加上冒号。这样,限,并在后面加上冒号。这样,限定词定词publicpublic之后的所有变量和函数不但可以被之后的所有变量和函数不但可以被同一个类的其它成员访问,还可以被程序中该同一个类的其它成员访问,还可以被程序中该类以外的对象访问。类以外的对象访问。一般,C+中定义类时,可将类的各个成员划分成不同的访问级别。这可以通过在
39、所说明的成员前面加上访问控制属性来实现。C+规定有三种访问控制属性:public表示成员是公有的,private表示成员是私有的,protected则表示成员是受保护的。public:公有成员,可以被任何函数访问(即可以从类的外部进行访问)。private:私有成员,只有类成员函数和友员类可以访问。protected:保护成员,只有类成员函数、派生类、友员类可以访问。缺省方式为private 类成员访问控制v 公有成员可以由程序中的任何函数访公有成员可以由程序中的任何函数访问,而私有成员只允许本类的成员函数访问,问,而私有成员只允许本类的成员函数访问,任何外部程序对它进行访问都是非法的。任何外
40、部程序对它进行访问都是非法的。v 可以看到,可以看到,私有成员是在类中被隐藏私有成员是在类中被隐藏的部分的部分,它往往是用来描述该类对象属性的,它往往是用来描述该类对象属性的一些数据成员,这些数据成员用户无法访问,一些数据成员,这些数据成员用户无法访问,只有通过成员函数或某些特殊说明的函数才只有通过成员函数或某些特殊说明的函数才可引用;可引用;v而公有成员一般是成员函数,它提供了而公有成员一般是成员函数,它提供了外部外部程序与类的接口程序与类的接口功能,用户通过公有成员访功能,用户通过公有成员访问该类对象中的数据。问该类对象中的数据。v 保护成员与私有成员在一般情况下含义相同,它们的区别体现在
41、类的继承中对产生的新类的影响不同。class myclassprivate:int a;public:void set_a(int num);int get_a();类myclass中的数据成员a是一个私有变量,故myclass以外的任何代码都不能访问它;set_a()和get_a()是myclass的成员函数,因此它们可以访问a;另外,由于set_a()和get_a()被说明为myclass的公有成员,所以允许类以外的其它程序代码调用它们。v 4.5.3 类的成员函数v 类中成员函数的原型声明写在类定义体内,用以说明该成员函数的形式参数和返回值类型,而成员函数的定义体一般写在类定义之外。同一
42、般函数一样,类的成员函数可以重载,也可以带有缺省的形参值。v 例4-1中,若将成员函数set_a()作如下定义:v void myclass:set_a(int num=10)v v a=num;v v 这样,如果在调用这个函数时没有给出实参,程序会把定义中默认的缺省形参值10赋给对象的私有成员a。v 在函数中有内联函数的概念。我们可以将那些仅由少数几条简单代码组成,却在程序中被频繁调用的函数定义为内联函数。程序在编译时,将内联函数的函数体插入到每一次调用它的地方。这样,在程序运行时就省去了调用这些函数引起的开销,提高了程序的执行效率。v 同样可以将类中的成员函数定义为内联函数,为此可采用如下
43、两种方式:v 将成员函数的函数体直接放在类声明中。v 使用inline关键字来限定,即在类定义体中说明函数原型时前面加上inline,或者在类定义体外定义这个函数时前面加上inline。v 是否将一个成员函数定义为内联函数是由这个函数的复杂性决定的。v【例4-2】类的成员函数的定义例题。vclass rectanglevprivate:vint x,y,weight,high;vpublic:vvoid move(int xx,int yy)x=xx;y=yy;vvoid size(int w,int h)weight=w;high=h;vvoid where(int&xx,int&yy)xx
44、=x;yy=y;vint area();int rectangle:area()return weight*high;下面给出一个关于日期的类的定义,该类是对日期的抽象,该类的对象将是某一个具体的日期。例:()、日期类的说明部份:class TDatepublic:void SetDate(int y,int m,int d);int IsLeapYear();void Print();private:int year,month,day;注:)、class:关键字。TDate:类名(大写字母 T 标识该名是 类名)。)、共有三个公有成员,均为成员函数。其中 SetDate():设 置日期,用
45、它使对象(变量)获取数值。IsLeapYear():用来判断是否闰年的函数。Print():用来将年、月、日 的具体值输出。)、请注意函数名的命名方法,它们往往用多个英文单词,每 个单词的第一个字母用大写,其余用小写,单词间不加任 何分隔,这是一种习惯性的约定。)、此外有三个私有成员,均为int 型变量 year、month、day。()、日期类的实现部分:void Tdate:SetDate(int y,int m,int d)/作用域运算符 :year=y;month=m;day=d;int Tdate:IsleapYear()return(year%4=0&year%100!=0)|(y
46、ear%400=0);void Tdate:Print()coutyear“,”month“,”dayendl;日期类的实现部份中,对类体说明的三个成员函数进行了定义,即具体给出了函数功能的实现。这里出现了作用域运算符:,用它来标识某个成员函数是属于哪个类的。该运算符在此的使用格式如下::关于日期的定义还可以如下所示:class Tdate public:void SetDate(int x,int y,int d)year=y;month=m;day=d;int IsLeapYear()return(year%4=0&year%100!=0)|(year%400=0);void Print(
47、)coutyear“,”month“,”dayendl;private:int year,month,day;这里,将对成员函数的实现(即函数的定义)都写在体内,因此类的实现部份被省略了。成员函数如果定义在体内,它将与 一般函数的定义一样;如果成员函数定义在类体外,则在函数头前面要加上该函数所属类的标识,就必须加上作用域运算符:。定义类时的注意事项1、在类体中不允许对所定义的数据成员初始化。private:int year=1998,month=4,day=8;/不允许初始化2、类中数据成员可以是任意的类型,如整型、浮点型、字符型、数组、指针和引用等。也可以是对象。而另一个类的对象,也可以作为
48、该类的成员,但自身类的对象是不行的,自身类的指针或引用又是可以的。当某类(类名)的对象n作为类 (类名)的成员时,如果类(类名)的定义在后,则需提前说明 例:class N;/提前说明类 N(类似于说明函数)class Mpublic:private:class N n;/n 是N 类的对象;class N public:void f(M m);/m 是M 类的对象;此处,M类中使用了N类的对象 n,而N 类的定义又在后面,所以,对 N 类要提前说明。而N类中又用了 M类的对象 m,则可以不必说明,因为 M定义在 N类之前。例:(点类)经常习惯地将类的定义的说明部份或者整个部分(包含实现部份)
49、放在一个头文件中。class TPoint /定义类public:/说明公有成员 void SetPoint(int x,int y);/说明公有成员函数 int Xcoord()return X;/说明并定义公有成员函数 int Ycoord()return Y;/同上 void Move(int xOffset,int yOffset);/说明公有成员函数private:/说明私有成员int X,Y;/私有成员数据;void TPoint:SetPoint(int x,int y)/在类体外定义成员函数X=x;Y=y;void TPoint:Move(int xOffset,int yOf
50、fset)/在类体外定义成员函数X+=xOffset;Y+=yOffset;#include#include /包含头文件,#include void main()TPoint p1,p2;/定义对象p1.SetPoint(3,5);/用对象引用成员函数p2.SetPoint(8,10);/用对象引用成员函数p1.Move(2,1);/用对象引用成员函数p2.Move(1,-2);/用对象引用成员函数coutx1=p1.Xcoord()y1=p1.Ycoord()endl;coutx2=p2.Xcoord()y2=p2.Ycoord()endl;/(8_2.h a8-2.cpp)x1=5y1=
侵权处理QQ:3464097650--上传资料QQ:3464097650
【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。