资源预览内容
第1页 / 共58页
第2页 / 共58页
第3页 / 共58页
第4页 / 共58页
第5页 / 共58页
第6页 / 共58页
第7页 / 共58页
第8页 / 共58页
第9页 / 共58页
第10页 / 共58页
亲,该文档总共58页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第6章 类与对象 6.1 面向对象程序设计的基本概念 6.2 类与对象的定义 6.3 对象的初始化 6.4 对象数组与对象指针 6.5 友元 6.6 类成员的共享与保护 6.7 程序实例,6.1 从面向过程到面向对象 6.1.1 面向对象程序设计的基本概念 1对象 对象(Object)是面向对象程序设计的核心,是程序的主要组成部分,一个程序就是一组对象的总和。 对象是由数据及对数据进行处理的方法和行为组成的。换言之,对象是具有某种特殊属性(数据)和行为方式(方法)的实体。 每个对象都有其自身的属性和行为。对同一类对象而言其对象的行为是相同的。但每个对象的属性(即状态)却是相对独立的。,2类 类是同一类型对象(具有相似行为的对象)的集合和抽象,是面向对象语言必须提供的由用户定义的数据类型,它将具有相同状态、行为和访问机制的多个对象抽象成一个类。定义类之后,属于这种类的一个对象称为类实例或类对象。类代表一般,而类的一个对象代表具体,描述了属于该类型的所有对象的性质。,3消息和方法 所谓消息(Message)就是用来请求对象执行某一处理或回答某些信息的要求,消息统一了数据和控制流。程序的执行是靠对象间消息的传递来完成的。 方法(Method)是类的行为属性的总称,是允许作用于该类对象上的各种操作。一个类可以有多个方法,表示该类所具有的功能和操作,通过对象调用类中的方法就可以改变对象域中变量的值。,4面向对象的基本特征 (1)封装性。封装性(Encapsulation)是指把对象属性和操作结合在一起,构成独立的单元,它的内部信息对外界是隐蔽的,不允许外界直接存取对象的属性,只能通过有限的接口与对象发生联系。,(2)继承性。类的继承性(Inheritance)指的是从已有的一个类可以构造新的类,使得新类具有原类的所有特性,并且新类还可以增加一些新的特性。 继承反映的是类与类之间抽象级别的不同,使得程序设计人员可以在已有的类的基础上定义和实现新类,所以有效地支持了软件组件的复用,使得当需要在系统中增加新特征时所需的新代码最少。,(3)多态性。对象根据接收的消息而做出动作,同样的消息被不同的对象接收时可导致完全不同的行动,这种现象称为多态性(Polymorphisn)。多态性机制不仅增加了面向对象软件系统的灵活性,进一步减少了信息冗余,而且显著地提高了软件的可重用性和可扩充性。,6.2.1 C+面向对象程序的结构 一个面向对象的C+程序一般由类的声明和类的使用两部分组成。类的使用部分一般由主函数和有关子函数组成。,6.2 类与对象的定义,以下是一个典型的C+程序结构。 #include using namespace std; /类的定义部分 class C int x,y,z; /类C的数据成员声明 f(); /类C的成员函数声明 ; /类的使用部分 void main() C a; /建立一个类C的对象a a.f(); /给对象a发消息,调用成员函数f() ,在C+程序中,程序设计始终围绕“类”展开。通过声明类,构建了程序所要完成的功能,体现了面向对象程序设计的思想。下面看一个具体的例子,直观地了解一下面向对象程序设计方法与结构化程序设计方法的区别。 【例6.1】 类的应用示例。,6.2.2 类的定义 在C+中,一个类指定一个独立的对象集合,该对象集合由组成该类的对象以及这些对象所允许的操作组成。,1类的定义形式 类定义的一般形式如下: class 类名 public: 数据成员或成员函数的定义 private: 数据成员或成员函数的定义 protected: 数据成员或成员函数的定义 ;,2类成员函数的定义 对类的成员函数的定义通常有两种形式,一种是在类的定义中直接定义函数,一种是在类外定义。前面的例6.1就是在类内部实现成员函数,下面再看一个例子。 【例6.2】 求 ,其中 。,按照类的定义形式,可以在类定义中只给出成员函数的原型,而在类外部定义具体的成员函数。这种成员函数在类外定义的一般形式如下: 函数返回值的类型 类名:函数名(形参表) (函数体) 其中双冒号:是作用域运算符,它指出该函数是属于哪一个类的成员函数。,6.2.3 对象的定义与使用 1对象的定义 对象的定义形式如下: 类名 对象名表; 其中对象名表代表有多个对象名,各对象名之间以逗号分隔。,2对象成员引用 具体引用形式为: 对象名.数据成员名 对象名.成员函数名(实参表) 【例6.3】 定义一个时钟类,类中有3个私有数据成员(Hour、Minute和Second)和两个公有成员函数(SetTime和ShowTime)。SetTime根据传递的3个参数为对象设置时间,ShowTime负责将对象表示的时间显示输出。在主函数中,建立一个时间类的对象,先利用默认时间设置,再设置时间为10时23分45秒并显示该时间。,6.2.4 类与结构体的区别 在C+语言中,结构体除了具有原先C语言定义的功能外,还具有类似于类的功能,即也可以在其中定义函数。它们之间的区别是:在结构体中,成员的默认访问权限是public,而类成员的默认访问权限是private。 【例6.4】 用结构体定义类的示例。,6.3 对象的初始化 在类的定义中不能给数据成员赋初值。 从封装的目的出发,类的数据成员应该多为私有的,对私有数据成员的访问只能通过成员函数,而不能通过成员引用的方式来赋值。 C+中定义了一种特殊的初始化函数,称之为构造函数(Constructor)。在特定对象使用结束时,还将进行一些清除工作。对象清除工作由析构函数(Destructor)来完成。,6.3.1 构造函数 1构造函数的特点 (1)构造函数名与类名相同,且没有返回值,不能指定函数类型。 (2)构造函数必须使具有公有属性,但它不能像其它成员函数那样被显式地调用,它是在定义对象的同时被系统自动调用的。 (3)构造函数是特殊的成员函数,函数体可以写在类体内,也可以写在类体外。 (4)构造函数可以重载,即一个类中可以定义多个参数个数或参数类型不同的构造函数。,【例6.5】 使用构造函数替代例6.3中SetTime()成员函数,并在主函数中,使用构造函数设置时间为15时19分56秒并显示该时间。 构造函数也可以重载。关于重载的概念将在第7章详细介绍,这里先看一个例子。 【例6.6】 构造函数重载定义示例。,综上所述,构造函数是一个有着特殊名字,在对象创建时被自动调用的一种函数,它的功能就是完成对象的初始化。,2默认的构造函数 如果类定义中没有给出构造函数,则C+编译器自动给出一个默认的构造函数,而且默认的构造函数只能有一个,形式如下: 类名:默认构造函数名() ,没有定义过任何形式的构造函数,系统会自动生成默认的构造函数。若已经定义过构造函数,则系统不会自动生成默认的构造函数,一旦需要,则要求显式地定义这种形式的构造函数。在程序中,若定义一个静态对象而没有指明初始值时,编译器会按默认的构造函数对对象的数据成员初始化为0或空。 【例6.7】 默认构造函数示例。 【例6.8】 构造函数的调用。,6.3.2 析构函数 1析构函数的特点 当对象创建时,会自动调用构造函数进行初始化。当对象撤消时,也会自动调用析构函数进行一些清理工作,如释放分配给对象的内存空间等。与构造函数类似的是:析构函数也与类同名,但在名字前有一个“”符号,析构函数也具有公有属性,也没有返回类型和返回值,但析构函数不带参数,不能重载,所以析构函数只有一个。 【例6.9】 析构函数程序举例。,2默认的析构函数 和默认构造函数一样,如果类定义中没有给出析构函数,系统也会自动生成一个默认的析构函数,其格式如下: 类名称:默认析构函数名() ,例如,编译系统为类Point生成默认的析构函数如下: Point:Point() 对于大多数类而言,默认的析构函数就能满足要求。只有在一个对象完成其操作之前需要做一些内部处理时,才显式地定义析构函数。,6.3.3 复制构造函数 复制构造函数的作用是使用一个已存在的对象去初始化另一个同类对象,它也是一种构造函数,除了具有一般构造函数的特征外,它还具有如下特点: (1)其形参必须是本类的对象的引用。 (2)某函数的形参是类的对象,调用该函数需要复制构造函数进行形参和实参结合。 (3)函数的返值是类的对象,函数调用返回的时候需要调用复制构造函数实现类对象的赋值。,复制构造函数的定义格式如下: 类名:复制构造函数名(const 类名 &对象名) (函数体) 复制构造函数与类同名,const是类型修饰符,被其修饰的对象是个不能被更新的常量。 【例6.10】 默认复制构造函数示例。 【例6.11】 复制构造函数示例。,普通构造函数在建立对象时被调用,而复制构造函数在用已有对象初始化一个新对象时被调用。复制构造函数被调用通常发生在以下3种情况: (1)程序中需要新建一个对象,并用一个类的对象去初始化类的另一个对象的时候。,(2)当对象作函数参数时,调用该函数时需要将实参对象完整地传递给形参,这就需要按实参复制一个形参,系统是通过调用复制构造函数来实现的,这样能保证形参具有和实参完全相同的值。,(3)当函数的返回值是类的对象。在函数调用完毕需要将返回值带回函数调用处时,此时需要将函数中的对象复制一个临时对象并传给该函数的调用处。 以上3种调用复制构造函数都是由编译系统自动完成的,不必由用户自己去调用。,6.4 对象数组与对象指针 6.4.1 对象数组 对象数组是指数组的每一个元素都是相同类型对象的数组,也就是说,若一个类有若干个对象,把这一系列的对象用一个数组来表示。对象数组的元素是对象,不仅具有数据成员,而且还有成员函数。,对象数组的定义和普通数组的定义类似,一般格式如下: 类名 数组名第一维大小第二维数组大小 其中,类名是指该数组元素属于该类的对象,方括号内的数组大小给出了某一维元素的个数。一维对象数组只有一对方括号,二维对象数组要有两个方括号对,等等。,与普通数组一样,在使用对象数组时也只能访问单个数组元素,也就是一个对象,通过这个对象,可以访问它的公有成员,一般形式如下: 数组名下标.成员名 和普通数组一样,对象数组既可以在定义时初始化,也可以在定义后赋值。 【例6.12】 对象数组应用示例。,6.4.2 对象指针 对象指针就是指向对象的指针,其定义的格式如下: 类名 *对象指针名; 对象成员也可以通过指向对象的指针来引用,引用数据成员的具体形式如下: 指向对象的指针-数据成员名,或: (*指向对象的指针).数据成员名 引用成员函数的具体形式如下: 指向对象的指针-成员函数名(实参表) 或: (*指向对象的指针).成员函数名(实参表) 【例6.13】 对象指针应用示例。,6.4.3 指向类成员的指针 1指向数据成员的指针 指向数据成员的指针定义格式如下: 类型说明符 类名:*数据成员指针名; 定义了指向数据成员的指针后,需要对其进行赋值,也就是要确定指向类的哪一个成员。对数据成员指针赋值的一般格式如下: 数据成员指针名=,将指针指向类的数据成员后,就可以通过类的对象引用指针所指向的数据成员,其格式有两种: 对象名.*数据成员指针名; 或: 对象指针名-*数据成员指针名; 【例6.14】 指向数据成员指针应用举例。,2指向成员函数的指针 指向成员函数的指针定义格式如下: 函数返回值类型 (类名:* 成员函数指针名)(参数表); 定义成员函数指针后要对其赋值,也就是确定指向类的哪一个成员函数。给指向成员函数指针赋值的一般格式如下: 成员函数指针名=,调用成员函数指针所指向函数的格式如下: (对象名.*成员函数指针名)(实参表) 或: (对象指针名-*成员函数指针名)(实参表) 【例6.15】 指向类成员函数指针应用
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号