谭浩强C程序设计第四版.ppt
《谭浩强C程序设计第四版.ppt》由会员分享,可在线阅读,更多相关《谭浩强C程序设计第四版.ppt(103页珍藏版)》请在三一办公上搜索。
1、第7章 类与对象,C+语言程序设计教程 第7章类与对象,第7章 类与对象,1.掌握类的定义,会根据需求设计类;2.会根据类创建各种对象;3.掌握对象的各种成员的使用方法;4.会设计构造函数与拷贝构造函数来初始化对象;理解其调用过程与顺序;5.理解浅拷贝与深拷贝的概念;6.掌握动态对象以及动态对象数组的建立与释放。7.理解类的静态成员的概念;8.理解友元函数与友元类的概念;9.掌握常对象与常成员的使用;10.了解对象在内存中的分布情况。,学习目标,C+语言程序设计教程 第7章类与对象,7.1 类与对象,在面向过程的结构化程序设计中,程序模块是由函数构成,函数将对数据处理的语句放在函数体内,完成特
2、定的功能,数据则通过函数参数传递进入函数体。在面向对象的程序设计中,程序模块是由类构成的。类是对逻辑上相关的函数与数据的封装,它是对问题的抽象描述。面向对象的程序设计方法就是运用面向对象的观点来对现实世界中的各种问题进行抽象,然后用计算机程序来描述并解决该问题,这种描述和处理是通过类与对象实现的。类与对象是C+程序设计中最重要的概念,C+语言程序设计教程 第7章类与对象,每一个实体都是对象,每个对象都属于一个特定的类型。在C+中对象的类型称为类(class)。类代表了某一批对象的共性和特征。类是对象的抽象,而对象是类的具体实例(instance)。正如同结构体类型和结构体变量的关系一样,人们先
3、声明一个结构体类型,然后用它去定义结构体变量。同一个结构体类型可以定义出多个不同的结构体变量。,结构体类型:struct Student int num;char name20;char sex;Student stud1,stud2;,类:class Student int num;char name20;char sex;void display()coutnum:numendl;coutname:nameendl;coutsex:sexendl;Student stud1,stud2,【例7-1】模拟时钟 分析:不管什么样的时钟,也不管各种时钟是如何运行的,它都具有时、分、秒3个属性。除
4、了运行、显示时间的基本功能外,还有设置(调整)时间、设置闹钟等功能。将时钟的这些属性与功能抽象出来,分别给出面向过程的程序与面向对象的程序来实现对时钟的模拟。思考:二者有何不同?,C+语言程序设计教程 第7章类与对象,运行结果:0:0:0-85893460:-85893460:-58934608:30:30 8:30:30,程序解释:通过对上述两种方案的程序进行简单的观察,可以发现它们存在下面几点不同:在程序A中,时钟数据用一个结构型的变量存储,对时钟数据的存取通过函数实现。由于存 储时钟数据的是一个全局变量,在任何地方都可见,可以不通过函数单独存取时钟数据。程序B中,只能通过类提供的函数操作
5、时钟。程序A中,数据与对数据操作相互独立,数据作为参数传递给函数。程序B中,数据与对数 据的操作构成一个整体。程序A与程序B运行的初始结果不同。这是因为在程序A中,变量是全局的;在程序B中,对 象(变量)MyClock是函数main()中的局部对象。全局变量与局部变量在没有初始化时,取初 值方式不同,这样造成了运行结果不同。将第23行移出main()外,使之变成全局对象后,两程序结果完全相同。在程序B中发现,一个以class开头的类似结构体的结构,将时钟的数据与对数据进行处理 的函数包括在一起,这就是用C+实现的类。,C+语言程序设计教程 第7章类与对象,7.1.2 类的定义,class 类名
6、 public:公有数据成员或公有函数成员的定义;protected:保护数据成员或保护函数成员的定义;private:私有数据成员或私有函数成员的定义;;,说明:关键字class表明定义的是一个类;类名是类的名称,应是一个合法的标识符;public、protected、private为存取控制属性(访问权限),用来控制对类的 成员的存取。如果前面没有标明访问权限,默认访问权限为private。类的成员有数据成员与函数成员两类,类的数据成员和函数成员统称为类的 成员,类的数据成员一般用来描述该类对象的属性,称为属性;函数成员是描 述类行为,称作方法。函数成员由函数构成,这些作为类成员的函数因此
7、也 叫成员函数。,简单讲,类是一个包含函数的结构体。因此,类的定义与结构类型的定义相似,其格式如下:,C+语言程序设计教程 第7章类与对象,7.1.2 类的定义,例如:例7-1中定义了一个时钟类Clock。,C+语言程序设计教程 第7章类与对象,在C+中也是先声明一个类类型,然后用它去定义若干个同类型的对象。对象就是类类型的一个变量。可以说类是对象的模板,是用来定义对象的一种抽象类型。类是抽象的,不占用内存,而对象是具体的,占用存储空间。在一开始时弄清对象和类的关系是十分重要的。类是用户自己指定的类型。如果程序中要用到类类型,必须自己根据需要进行声明,或者使用别人已设计好的类。C+标准本身并不
8、提供现成的类的名称、结构和内容。在C+中声明一个类类型和声明一个结构体类型是相似的。,1.数据成员 类定义中的数据成员描述了类对象所包含的数据类型,数据成员的类型可以是C+基本数据类型,也可以是构造数据类型。struct Record char name20;int score;class Team private:int num;/基本数据类型 Record*p;/构造数据类型;,C+语言程序设计教程 第7章类与对象,class Team;/已定义的类class Grade Team a;/使用了已定义的类类型Grade*p;/使用正在定义的类类型定义指针成员Grade,注意:因为类只是一种
9、类型,类中的数据成员不占内存空间,因此在定义数据成员 时不能给数据成员赋初值。类的数据成员除了可以使用前面讲述的C+类型外,还可以使用已定义完整的 类类型。在正在定义的类中,由于该类型没有定义完整,所以不能定义该类类型的变 量,只能定义该类类型的指针成员以及该类类型的引用成员。,C+语言程序设计教程 第7章类与对象,2.成员函数 作为类成员的成员函数描述了对类中的数据成员实施的操作。成员函数的定义、声明格式与非成员函数(全局函数)的格式相同。成员函数可以放在类中定义,也可以放在类外。放在类中定义的成员函数为内联(inline)函数。Clock类中的成员函数就是放在类内定义的。C+可以在类内声明
10、成员函数的原型,在类外定义函数体。这样做的好处是相当于在类内列了一个函数功能表,使我们对类的成员函数的功能一目了然,避免了在各个函数实现的大堆代码中查找函数的定义。在类中声明函数原型的方法与一般函数原型的声明一样,在类外定义函数体的格式如下::是类的作用域分辨符,用在此处,放在类名后成员函数前,表明后面的成员函数属于前面的那个类。,返回值类型 类名:成员函数名(形参表)函数体;,C+语言程序设计教程 第7章类与对象,Clock类中的成员函数可以在类中声明:class Clock private:int H,M,S;public:void SetTime(int h,int m,int s);/
11、声明成员函数 void ShowTime();/声明成员函数;在类外实现成员函数如下:void Clock:SetTime(int h,int m,int s)H=h,M=m,S=s;;void Clock:ShowTime()coutH:M:Sendl;,C+语言程序设计教程 第7章类与对象,如果要将类外定义的成员函数编译成内联函数,可以在类外定义函数时,函数的返回类型前加上inline;下面将ShowTime()定义成内联函数,与在类内定义成员函数的效果相同。inline void Clock:ShowTime()coutH:M:Sendl;3.类作用域 类是一组数据成员和函数成员的集合,
12、类作用域作用于类中定义的特定的成员,包括数据成员与成员函数,类内的每一个成员都具有类作用域。实际上,类的封装作用也就是限制类的成员其访问范围局限于类的作用域之内。,C+语言程序设计教程 第7章类与对象,class Clock private:int H,M,S;public:Clock AddTime(Clock C2)/形参为Clock类型的变量 Clock T;/函数体中定义了Clock类型的变量.return T;/返回类型为Clock类型;,C+语言程序设计教程 第7章类与对象,注意:在成员函数中不仅可以自由使用类的成员,还可以使用该类定义变量(对象),通过变量使用成员。其原因是函数在
13、调用时才在栈内存中建立函数体中的变量(包括实参),这时类已经定义完毕,当然可以使用已定义完整的类类型的变量。,7.1.3 对象的建立与使用,类相当于一种包含函数的自定义数据类型,它不占内存,是一个抽象的“虚”体,使用已定义的类建立对象就像用数据类型定义变量一样。对象建立后,对象占据内存,变成了一个“实”体。类与对象的关系就像数据类型与变量的关系一样。其实,一个变量就是一个简单的不含成员函数的数据对象。类名 对象名;建立对象的格式如下:其中,对象名可以是简单的标识符,也可以是数组。在例7-1中,使用:Clock MyClock;建立了一个Clock型的对象MyClock。,C+语言程序设计教程
14、第7章类与对象,类名 对象名;,在建立对象后,就可以通过对象存取对象中的数据成员,调用成员函数。存取语法如下:例如,通过对象MyClock使用成员函数SetTime()的方式如下:MyClock.SetTime(8,30,30);至于对数据成员H、M、S的存取,因其存取权限为pravate而被保护,所以不能进行直接存取。,C+语言程序设计教程 第7章类与对象,对象名.属性 对象名.成员函数名(实参1,实参2,),注意:为节省内存,编译器在创建对象时,只为各对象分配用于保存各对象数据成员初始化的值,并不为各对象的成员函数分配单独的内存空间,而是共享类的成员函数定义,即类中成员函数的定义为该类的所
15、有对象所共享,这是C+编译器创建对象的一种方法,在实际应用中,我们仍要将对象理解为由数据成员和函数成员两部分组成。,7.1.4 成员的存取控制,通过设置成员的存取控制属性,使对类成员的存取得到控制,从而达到了信息隐藏的目的。C+的存取控制属性有:公有类型(public)、私有类型(private)和保护类型(protected)。三者的意义如下:表7-1 存取控制属性表,C+语言程序设计教程 第7章类与对象,类中定义为public等级的成员,可以被该类的任何对象存取,适用于完全公开的数据。而private等级的成员只可被类内的成员存取,适用于不公开的数据。至于protected等级,属于半公开
16、性质的数据,定义为protected等级的成员,可以被该类及其子类存取。关于子类的概念,在以后的章节中讲述。,在Clock类中,H、M、S的存取控制属性为privated。这样,这些数据不能在类外存取而被保护,下列存取方法是错误的:MyClock.M=30;而成员函数SetTime()、ShowTime()存取控制属性为public,因此在类外可以通过对象存取。由于private成员被隐藏起来,不能直接在类外被存取,为了取得这些被隐藏的数据,通常在类内定义一个public的成员函数,通过该成员函数存取private成员,而public的成员函数又能在类外被调用。这样通过调用public型的成员
17、函数,间接存取到private成员。这样的函数起到了为private成员提供供外界访问的接口作用。类Clock中成员函数SetTime()、ShowTime()就是存取private数据成员H、M、S的接口。通过接口访问类的数据成员,一方面有效保护数据成员,另一方面又保证了数据的合理性。,C+语言程序设计教程 第7章类与对象,7.2 构造函数与析构函数,在定义一个对象的同时,希望能给它的数据成员赋初值对象的初始化。在特定对象使用结束时,还经常需要进行一些清理工作。C+程序中的初始化和清理工作分别由两个特殊的成员函数来完成,它们就是构造函数和析构函数。,C+语言程序设计教程 第7章类与对象,7.
18、2.1 构造函数,构造函数(constructor)构造函数是与类名相同的,在建立对象时自动调用的函数。如果在定义类时,没有为类定义构造函数,编译系统就生成一个默认形式的隐含的的构造函数,这个构造函数的函数体是空的,因此默认构造函数不具备任何功能。如果用户至少为类定义了一个构造函数,C+就不会生成任何默认的构造函数,而是根据对象的参数类型和个数从用户定义的构造函数中选择最合适的构造函数完成对该对象的初始化。作为类的成员函数,构造函数可以直接访问类的所有数据成员,可以是内联函数,可以不带任何参数,可以带有参数表以及默认形参值,还可以重载,用户可以根据不同问题的具体需要,有针对性地设计合适的构造函
19、数将对象初始化为特定的状态。,C+语言程序设计教程 第7章类与对象,例如,将例7-1 程序p7-1_b.cpp中的Clock类中添加带有默认形参值的构造函数:Clock(int h=0,int m=0,int s=0)H=(h=0显示结果为:9:30:45这是因为建立对象时调用了Clock(9,30,45),C+语言程序设计教程 第7章类与对象,构造函数是类的一个成员函数,除了具有一般成员函数的特征之外,还归纳出如下特殊的性质:构造函数的函数名必须与定义它的类同名。构造函数没有返回值。如果在构造函数前加void是错误的。构造函数被声明定义为公有函数。构造函数在建立对象时由系统自动调用。注意:由
20、于构造函数可以重载,可以定义多个构造函数,在建立对象时根据参数来调用相应的构造函数。如果相应的构造函数没有定义,则出错。例如,若定义例7-1中的构造函数,而不是带默认形参值的构造函数:Clock(int h,int m,int s)H=(h=0时,调用Clock(),而Clock类没有Clock()函数,因而出错。,C+语言程序设计教程 第7章类与对象,7.2.2 析构函数,自然界万物都是有生有灭,程序中的对象也是一样。对象在定义时诞生,不同生存期的对象在不同的时期消失。在对象要消失时,通常有一些善后工作需要做,例如:构造对象时,通过构造函数动态申请了一些内存单元,在对象消失之前就要释放这些内
21、存单元。C+用什么来保证这些善后清除工作的执行呢?答案是:析构函数。析构函数(destructor)也译作拆构函数,是在对象消失之前的瞬间自动调用的函数,其形式是:构造函数名(类名)前加上一个逻辑非运算符,以示与构造函数相反。析构函数与构造函数的作用几乎正好相反,相当于“逆构造函数”。析构函数也是类的一个特殊的公有函数成员,,C+语言程序设计教程 第7章类与对象,构造函数名();,7.2.2 析构函数,析构函数具有以下特点:析构函数没有任何参数,不能被重载,但可以是虚函数,一个类只有一个析构函数。析构函数没有返回值。析构函数名与类名相同,但在类名前加上一个逻辑非运算符“”,以示与构造函数对比区
22、别。析构函数一般由用户自己定义,在对象消失时由系统自动调用,如果用户没有定义析构函数,系统将自动生成一个不做任何事的默认析构函数。,C+语言程序设计教程 第7章类与对象,注意:在对象消失时的清理工作并不是由析构函数完成,而是靠用户在析构函数中添加清理语句完成。,C+语言程序设计教程 第7章类与对象,运行结果:constructor:8:0:0constructor:9:0:0constructor:10:0:0constructor:11:0:0destructor:11:0:0destructor:10:0:0,C+语言程序设计教程 第7章类与对象,C+语言程序设计教程 第7章类与对象,运行
23、结果:string:ABCDE,length:5string:123456,length:6,C+语言程序设计教程 第7章类与对象,7.2.3 拷贝构造函数,拷贝构造函数是与类名相同,形参是本类的对象的引用的函数,在用已存在对象初始化新建立对象时调用。类的拷贝构造函数一般由用户定义,如果用户没有定义拷贝构造函数,系统就会自动生成一个默认函数,这个默认拷贝构造函数的功能是把初始值对象的每个数据成员的值依次复制到新建立的对象中。因此,也可以说是完成了同类对象的克隆(Clone)。这样得到的对象和原对象具有完全相同的数据成员,即完全相同的属性。,C+语言程序设计教程 第7章类与对象,用户可以也可以根
24、据实际问题的需要定义特定的拷贝构造函数来改变缺省拷贝构造函数的行为,以实现同类对象之间数据成员的传递。如果用户自定义了拷贝构造函数,则在用一个类的对象初始化该类的另外一个对象时,自动调用自定义的拷贝构造函数。定义一个拷贝构造函数的一般形式为:拷贝构造函数在用类的一个对象去初始化该类的另一个对象时调用,以下三种情况相当于用一个已存在的对象去初始化新建立的对象,此时,调用拷贝构造函数:当用类的一个对象去初始化该类的另一个对象时。如果函数的形参是类的对象,调用函数时,将对象作为函数实参传递给函数的形参时。如果函数的返回值是类的对象,函数执行完成,将返回值返回时。,类名(类名,C+语言程序设计教程 第
25、7章类与对象,C+语言程序设计教程 第7章类与对象,运行结果:constructor:8:0:0constructor:9:0:0copy constructor,before call:-858993460:-858993460:-858993460copy constructor,before call:1310592:4200534:1310568copy constructor,before call:-858993460:-858993460:-858993460destructor:9:0:0destructor:9:0:0constructor:0:0:0destructor:9
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 谭浩强 程序设计 第四
链接地址:https://www.31ppt.com/p-5386284.html