章类和对象.ppt

上传人:本田雅阁 文档编号:2752021 上传时间:2019-05-11 格式:PPT 页数:58 大小:747.02KB
返回 下载 相关 举报
章类和对象.ppt_第1页
第1页 / 共58页
章类和对象.ppt_第2页
第2页 / 共58页
章类和对象.ppt_第3页
第3页 / 共58页
章类和对象.ppt_第4页
第4页 / 共58页
章类和对象.ppt_第5页
第5页 / 共58页
点击查看更多>>
资源描述

《章类和对象.ppt》由会员分享,可在线阅读,更多相关《章类和对象.ppt(58页珍藏版)》请在三一文库上搜索。

1、第4章 类和对象,4.1 类和对象 4.2 构造函数和析构函数 4.3 类的组合 4.4 UML图形标识 4.5 结构体和联合体 4.6 小结,一个简单的日期类,数据抽象: 行为抽象: 年 设置年月日 月 判断是否为闰年 日 显示时间 用C语言可以将年月日描述为: 日期类(TDate) 数据抽象: int Year,Month,day; 代码抽象: SetDate();IsleapYear();Print();,4.1 类和对象,4.1.1 什么是类 4.1.2 类的定义格式 4.1.3 类成员的访问控制 4.1.4 类的数据成员 4.1.5 类的成员函数 4.1.6 定义类时的注意事项 4.

2、1.7 对象,4.1.1 什么是类,类是一种复杂数据类型; 类是将不同类型的数据和与这些数据相关的操作封装在一起的集合体;类中的数据具有隐藏性; 类是对某一类对象的抽象,对象是某一种类的实例; C+提供了类的继承机制; 类是面向对象程序设计的核心; 类是C+实现抽象数据类型的工具;,1、类定义格式的构成 说明部分:说明类中的成员,包含数据成员和成员函数的说明; 实现部分:对成员函数的定义; 2、类的一般定义格式,4.1.2 类的定义格式,4.1.2 类的定义格式(续1),class Date /日期类的定义 public: void SetDate(int y,int m,int d); in

3、t IsLeapYear(); void PrintDate(); private: int year,month,day; ; /时钟类的定义 class Clock public: void SetTime(int NewH,int NewM,int NewS); void ShowTime(); private: int Hour,Minute,Second; ;,4.1.3 类成员的访问控制,访问权限修饰符: 公有的(public) /公有部分提供一些操作(即成员函数),是提供给用户的接口功能; 私有的(private) /私有部分提供一些数据成员,通常用来描述该类中的对象的属性;缺省

4、访问权限 保护的(protected) 访问权限修饰符出现的先后次序无关,并且允许多次出现;,4.1.3 类成员的访问控制(续1),通过private、protected、public来指定成员的不同访问权限,class,private: protected: public:,4.1.4 类的数据成员,一、数据成员 数据成员可以放在公有部分,称为公有数据成员,也可以放在私有或保护部分,称为私有数据成员或保护数据成员。 二、数据成员在类体中的定义格式为: 数据成员; (1)数据成员只有,无说明。 (2)在类体中不允许对所定义的数据成员进行初始化。 class Clock public: void

5、 SetTime(int NewH,int NewM,int NewS); private: int Hour=0,Minute=0,Second=0;/出错; (3)数据成员的类型可以为任意类型(基本数据类型、复杂数据类型、已定义类的对象等)。,4.1.5 类的成员函数,类的成员函数的原型声明必须在类主体中,函数的实现可以在类主体中(内联函数),也可以在类主体外(外联函数)。 1.成员函数的实现形式: 返回值类型 类名:成员函数名(参数表) 函数体 在类的成员函数体内,可以直接访问该类的所有数据成员,包括:public、protected、private。 类的成员函数也可带默认形参值,4.

6、1.5 类的成员函数(续1),class TDate public: void SetDate(int y,int m,int d); int IsLeapYear(); void Print(); private: int year,month,day; ; void TDate:SetDate(int y,int m,int d) y=year; / m=month; d=day; ,作用域运算符,例4-1 简单的日期程序(tdate.h),/成员函数声明,/成员函数定义,year=y; month=m; day=d;,4.1.5 类的成员函数(续2),int TDate:IsLeapYe

7、ar()/成员函数定义 return (year%4=0 ,作用域运算符:,作用: 标识某个成员属于哪个类;,格式: :(),4.1.5 类的成员函数(续3),2.带默认值的成员函数 void TDate:SetDate(int y=2009,int m=2,int d=1) year=y; month=m; day=d; 3.内联成员函数显式声明与隐式声明 class TDate public: void SetDate(int y,int m,int d); int IsLeapYear(); void Print() /内联成员函数隐式定义 coutyear“.“month“.“daye

8、ndl; private: int year,month,day; ;,3.内联成员函数和外联成员函数,内联函数:定义在类体内的成员函数,或定义在类体外,但使用inline关键字进行说明的成员函数; 外联函数:说明在类体内,定义在类体外的成员函数; 例4.2:分析下列程序的输出结果。 #include using namespace std; class A public: A(int x,int y)X=x;Y=y; int a() return X; int b() return Y; int c(); int d(); private: int X,Y; ;,inline int A:c

9、() return a()+b(); inline int A:d() return c(); void main() A m(3,5); int i=m.d(); cout“d() return:” iendl; ,输出: d() return:8,4.1.6 定义类时的注意事项,1.在类体中不允许对所定义的数据成员进行初始化;,class TDate public: private: int year(2009),month(2),day(5); ;,错误,2.类中的数据成员的类型可以是任意的;,包含整型、浮点型、字符型、数组、指针和引用等;,另一个类的对象,可以作该类的成员(类的组合);

10、,自身类的对象不可以作该类的成员;,4.1.6 定义类时的注意事项(续1),class N; class M public: . private: N *n; ; class N public: void f(M m); ;,/前向引用声明,自身类的指针或引用,可以作该类的成员(递归类);,当另一个类的对象作为该类的成员时,如果另一个类的定义在后,需要提前说明,称为前向引用声明;,一般在类体内先说明用户感兴趣的公有成员,再说明私有成员;,习惯将类定义的说明部分或者整个定义部分(包含实现部分)放到一个头文件中;,/n是N类的对象,/m是M类的对象,4.1.7 对象,.运算符:表示对象的成员,例如

11、: date1.year,date1.month,date1.day; date1.SetDate(1998,4,9);,4.1.7 对象(续1),-运算符与.运算符的区别,-表示指向对象的指针的成员 .表示一般对象的成员;,两种等价表示,-,(*).,3、引用对象,与一般对象相同;,2、指针对象,数据成员: -,成员函数: -(),-运算符:表示指针对象的成员,例如: Pdate-year,Pdate-SetDate(2009,2,9);,/tdate.h 类定义部分_头文件 class TDate public: void SetDate(int y,int m,int d); int I

12、sLeapYear(); void Print() coutyear“.“month“.” day endl; private: 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)| (year%400=0);,4.1.7 对象(续2),#include using namespace std; #include “tdate.h“ void main() T

13、Date date1,date2; date1.SetDate(2009,2,4); date2.SetDate(2010,9,5); int leap=date1.IsLeapYear(); coutleapendl; date1.Print(); date2.Print(); ,输出 0 2009.2.4 2010.9.5,例4.3:分析下列程序的输出结果。,4.2 构造函数和析构函数,构造函数与析构函数是功能特殊的成员函数; 构造函数:在创建对象时,使用特定的值来将对象初始化; 析构函数:用来释放对象,在对象删除前做一些清理工作; 4.2.1 构造函数和析构函数 4.2.2 构造和析构函

14、数的调用顺序 4.2.3 缺省构造函数和缺省析构函数 4.2.4 拷贝构造函数 4.2.5 设置参数的缺省值,4.2.1 构造函数和析构函数,例4-4 构造函数与析构函数(tdate1.h),class TDate1 public: TDate1(int y,int m,int d);/构造函数 TDate1(); /析构函数 void Print() coutyear“.“month“.“dayendl; private: int year, month, day; ; TDate1:TDate1(int y,int m,int d)/构造函数 year=y; month=m; day=d;

15、 cout“Constructor called.“endl; TDate1:TDate1() /析构函数的实现 cout“Destructor called.“endl;,4.2.1 构造函数和析构函数(续4),#include using namespace std; #include “tdate1.h“ void main( ) TDate1 today(2010,9,5),tomorrow(2010,9,6); cout“Today is “; today.Print(); cout“Tomorrow is “; tomorrow.Print(); ,输出: Constructor

16、called. Constructor called. Today is 2010.9.5 Tomorrow is 2010.9.6 Destructor called. Destructor called.,例4.5:分析下列程序的输出结果。,4.2.1 构造函数和析构函数(续2),2、构造函数的特点,3、析构函数的特点,构造函数是公有成员函数,函数在类体中声明, 定义可写在类体内,也可写在类体外;,构造函数的名字与类名相同;,构造函数不指定返回类型,它有隐含的返回值,该值由系统内部使用;,析构函数也是公有成员函数,函数在类体中声明, 定义可写在类体内,也可写在类体外;,析构函数的名字在类名

17、前加字符;,析构函数不指定返回类型;,4.2.1 构造函数和析构函数(续3),2、构造函数的特点,3、析构函数的特点,构造函数可以有一个或多个参数;,析构函数没有参数;,构造函数可以重载;,在程序中不直接使用构造函数,在创建对象时系统自动调用构造函数;,一个类中只能定义一个析构函数;,析构函数在对象存在的函数体结束时或使用delete运算符释放new运算创建的对象时被自动调用; 析构函数的调用次序与构造函数调用次序相反;,4.2.2 构造函数和析构函数的调用顺序,构造函数是在对象建立时调用,析构函数是在对象撤销时调用,调用析构函数的顺序和构造函数的顺序正好相反。 例4.6 构造函数与析构函数的

18、调用次序 #include using namespace std; class Counter public: Counter(int id); Counter(); private: int who; ;,4.2.2 构造函数和析构函数的调用顺序(续1),Counter:Counter(int id) who=id; cout“Object“who“ initialized!n“; Counter:Counter() cout“Object“who“ destroyed!n“; void main() Counter c1(1),c2(2); cout“OK!n“; ,输出: Object

19、 1 initialized ! Object 2 initialized ! OK! Object 2 destroyed ! Object 1 destroyed !,4.2.3 缺省构造函数和缺省析构函数,:() 函数体 ,1、缺省构造函数,类定义中没有任何构造函数时,由编译器自动生成一个不带参数的缺省构造函数;,缺省构造函数即参数表为空的构造函数;,:() 函数体 ,2、缺省析构函数(定义时机同缺省构造函数),类名,4.2.4 设置参数的缺省值,一般成员函数和构造函数都可以被设置缺省参数值。 例4.7:分析下列程序的输出结果。,#include using namespace std;

20、 class N public: N(int a=3,int b=5,int c=7); int Aout() return A; int Bout() return B; int Cout() return C; private: int A,B,C; ;,构造函数设置缺省参数值,4.2.4 设置参数的缺省值(续1),N:N(int a,int b,int c) A=a; B=b; C=c; void main() N X,Y(9,11),Z(13,15,17); cout“X=“X.Aout()“, “X.Bout() “, “X.Cout()endl; cout“Y=“Y.Aout()“

21、, “Y.Bout() “, “Y.Cout()endl; cout“Z=“Z.Aout()“, “Z.Bout() “, “Z.Cout()endl; ,输出: X=3,5,7 Y=9,11,7 Z=13,15,17,4.2.5 拷贝构造函数,1、功能,用一个已知的对象来初始化一个被创建的同类对象;,2、特点,函数名同类名,无返回类型;,只有一个参数,是对某个对象的引用;,每个类都必须有一个拷贝初始化构造函数;,:(& ),3、缺省拷贝初始化构造函数,如果类中没有说明拷贝初始化构造函数,则编译系统自动生成一个具有上述形式的缺省拷贝初始化构造函数,作为该类的公有成员;,4.2.5 拷贝构造函数

22、(续1),/tpoint.h class Point public: Point(int i,int j);/一般构造函数 Point(const Point ,例4.8:分析下列程序的输出结果。,4.2.5 拷贝构造函数(续2),Point:Point(const Point ,4.2.4 拷贝构造函数(续3),#include /主函数 #include “tpoint.h“ Point func(Point Q); /对象Q作为func的形参 void main() Point M(20,30),P(0,0); Point N(M);/用M初始化N,调用拷贝构造函数(1) cout“即将

23、调用func()函数,注意各构造函数的调用次数!n“; P=func(N);/对象N作为func的实参,调用拷贝构造函数(2) cout“P=“P.ReadX()“,“ P.ReadY()endl; Point func(Point Q) /普通函数,返回值为Point类 cout“n已进行到func()的函数体内!n“; cout“定义对象R,则“; Point R(Q.ReadX()+10,Q.ReadY()+20); return R; /函数返回值是类对象,返回时调用拷贝构造函数(3),4.2.5 拷贝构造函数(续4),输出: 一般构造函数第1次被调用! 一般构造函数第2次被调用! 拷

24、贝构造函数第1次被调用! 即将调用func()函数,注意各构造函数的调用次数! 拷贝构造函数第2次被调用! 已进行到func()的函数体内! 定义对象R,则一般构造函数第3次被调用! 拷贝构造函数第3次被调用!/匿名对象 析构函数第1次被调用! 析构函数第2次被调用! 析构函数第3次被调用! P=30,50 析构函数第4次被调用! 析构函数第5次被调用! 析构函数第6次被调用!,4.2.5 使用系统默认拷贝构造函数(续5),class Point public: Point(int i,int j);/一般构造函数 / Point(Point ,void main() Point M(20,3

25、0),P(0,0); Point N(M);/用M初始化N,调用默认拷贝构造函数 cout“即将调用func()函数,注意各构造函数的调用次数!n“; P=func(N); cout“P=“P.ReadX()“,“P.ReadY()endl; ,4.2.5 使用系统默认拷贝构造函数(续6),结果: 一般构造函数第1次被调用! 一般构造函数第2次被调用! 即将调用func()函数,注意各构造函数的调用次数! 已进行到fun()的函数体内! 定义对象R,则一般构造函数第3次被调用! 析构函数第1次被调用! 析构函数第2次被调用! 析构函数第3次被调用! P=30,50 析构函数第4次被调用! 析构

26、函数第5次被调用! 析构函数第6次被调用!,系统默认拷贝构造函数的功能是把初始对象的每个数据成员的值都复制到新建对象中. 有 X:X(const X .,4.2.5 拷贝构造函数(续7),4、拷贝构造函数的调用时机 缺省拷贝构造函数在某些场合调用会产生程序隐患,必须清楚其调用时机. 由一个类的对象M初始化该类另一个对象N时; 例如:TPoint N(M); 当类的对象N作为函数实参传递给函数形参时(传值调用); 例如:P=f(N); 函数返回值是类的对象,函数调用返回R时(数据值); 例如:return R;,例9:构造函数的重载,#include class Complex public:

27、Complex(double r,double i)real=r; imag=i; Complex(void)real=0.0; imag=0.0; Complex(const Complex ,4.3 类的组合,指一个类内嵌其他类的对象作为成员的情况,两个类间为包含与被包含的关系。 当创建类的对象时,若有内嵌对象成员时,内嵌成员也会被自动创建。因而在创建对象时既要对本类的基本数据成员进行初始化,也要对内嵌成员进行初始化。,4.3 类的组合,组合类构造函数定义的一般形式: 类名:类名(形参表):内嵌对象1(形参表1),内嵌对象2(形参表2), 类的初始化 例:M:M(int x,int y):

28、a(x),b(y)xx=x;yy=y; 类中一般数据成员也可以采用此形式进行初始化: 类名:类名(形参表):私有数据成员1(值1),私有数据成员2(值2), 例:M:M(int x,int y):a(x),b(y),xx(x),yy(y),4.3 类的组合(续1),例4-10 类的组合线段Line类。 Line类的数据成员包括Point类的两个对象p1和p2。 Line类的主要功能用来计算两点间距离,在构造函数中实现。,4.3 类的组合(续2),/Point.h class Point public: Point(int xx=0,int yy=0)X=xx;Y=yy; Point(Point

29、 ,4.3 类的组合(续2),/Line.h #include using namespace std; class Line public: Line(Point xp1,Point xp2);/组合类构造函数 Line(Line ,4.3 类的组合(续3),Line:Line(Point xp1,Point xp2):p1(xp1),p2(xp2) cout“Line构造函数被调用!“endl; double x=double(p1.GetX()-p2.GetX(); double y=double(p1.GetY()-p2.GetY(); len=sqrt(x*x+y*y); Line:

30、Line(Line ,4.3 类的组合(续4),/主程序 #include using namespace std; #include “Point.h“ #include “Line.h“ void main() Point myp1(1,1),myp2(4,5); Line line1(myp1,myp2); Line line2(line1); cout“the Line1 is:“; coutline1.getLine()endl; cout“the Line1 is:“; coutline2.getLine()endl; ,结果: Point拷贝构造函数被调用Point拷贝构造函数被

31、调用Point拷贝构造函数被调用Point拷贝构造函数被调用Line构造函数被调用 Point拷贝构造函数被调用Point拷贝构造函数被调用Line拷贝构造函数被调用 The Line1 is:5 The Line2 is:5,4.4 UML图形标识,UML(Unified Modeling Language统一建模语言)是一个复杂庞大的面向对象的系统建模语言.不是编程语言 UML语言中用符号描述概念,概念间关系描述为连接符号的线. UML内容:各种类型的图形,分别描述软件模型的静态结构、动态行为、模块组织和管理 本章介绍UML类图,属于静态结构图的一种,能够准确而清楚地描述以下问题: 1)类

32、:包括成员数据和成员函数(或方 法) 2)对象:类的实例 3)类的继承或包含 4)类及对象之间的关系,相互作用与消息传递等,4.4.1 UML类图,类图:由类和与之相关的各种静态关系共同组成的图形 对象图:一个包含了对象而没有包含类的类图。 静态对象图:特定对象图的一个实例。 类图使用上下分为三段的矩形表示,上部为类名,中部为数据成员(数据,UML中称属性),下部为该类的函数成员(行为,UML中称操作)。,4.4.1 UML类图(续1),数据成员表示的语法: 访问控制属性 名称 重数 :类型 =默认值 约束特征 *访问控制属性:+、-、#分别为公有、私有、保护 *名称:数据成员名 *重数:属性

33、的重数 *类型:数据成员的种类(基本和复杂数据类型) *默认值:数据成员的初始值 *约束特征:数据成员的约束说明。如“只读” 例:- X:int + size: Area = (100,100),4.4.1 UML类图(续2),成员函数表示的语法: 访问控制属性 名称 (参数表) :返回类型 约束特性 *访问控制属性:+、-、#分别为公有、私有、保护 *名称:成员函数名 *参数表:方向 名称:类型 = 默认值, 方向: in(输入), out(输出),inout(输入和输出).表示参数的传递方向. *返回值类型:该成员函数返回的类型 *约束特性:对成员函数性质的约束说明。 例: + GetX(

34、): int + SetTime(NewH:int=0,NewM:int=0,NewS:int=0):void,4.4.2 UML对象图,UML语言中用一个矩形表示一个对象图,对象的名字加下划线,格式“对象名:类名”; 数据成员及其值在下面区域,是可选的.,4.4.3 几种关系的图形标识,依赖关系 类或对象之间的依赖关系描述了一个事物的变化可能会影响到使用它的另一个事物, 反之不成立.,重数标记: * 表示任何数目的对象 n 即恰好n个对象; 01 即0个或1个对象(关联可选),4.4.3 几种关系的图形标识(续1),(3) 包含关系(聚集和组合) 聚集: 类之间的关系是整体与部分的关系. 如

35、:包含、组成、分为部分,等都是聚集. 进一步划分: 共享聚集: 部分可以参加多个整体 组成聚集 (组合):整体拥有各部分,部分与整体共存. 组合是一种简单聚集形式,但它具有更强的拥有关系.,4.4.3 几种关系的图形标识(续2),例:,1 *,-p1 -p2 2,单向组合:直线段包括端点p1,p2,4.4.3 几种关系的图形标识(续3),(4) 继承关系(泛化) 用带三角形标识的直线段表示继承关系.三角的尖指向父类,对边上的线指向子类.,4.5 结构体和联合体,C+保留并扩展了C中的结构体和联合体。,struct 结构体名称 公有成员 /默认访问权限 protected: 保护型据成员 pri

36、vate: 私有成员 ;,class 类名称 私有成员 /默认访问权限 protected: 保护型成员 public: 公有成员 ;,union 联合体名称 公有成员 /默认访问权限 protected: 保护型成员 private: 私有成员 ;,因联合体成员共用相同的内存单元,因而对联合体有一些限制,各对象不能有自定义构造和析构函数,不能继承等。一般只用结构体和联合体存储一些公有的数据,而不为它们定义函数成员,小 结,1C+中class类是C语言结构体的延伸,把结构体引申为类,结构体变量就引申为对象,并把成员函数纳入其中。 表4.1 C语言的结构体与C+的类对照表,小 结,2.类是面向对象程序设计的基本单元,封装有两种成员: 数据成员 /描述该类对象的属性 成员函数 /对象的方法和行为 3.访问控制: 公有部分(消息通路)、私有部分(信息隐藏)或保护部分 4.构造函数和析构函数是创建对象和撤消对象的特殊成员函数,构造函数可以重载,析构函数只能有一个。 5.拷贝构造函数用于(1)用一个对象初始化另一个对象;(2)用对象进行参数虚实结合;(3)用对象做返回值. 6.系统自动为没有构造函数、拷贝构造函数和析构函数的类提供默认函数。 7.UML图形标识. 8.C+扩展了结构体和联合体,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1