c++类的建立及应用_第1页
c++类的建立及应用_第2页
c++类的建立及应用_第3页
c++类的建立及应用_第4页
c++类的建立及应用_第5页
已阅读5页,还剩66页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Chapter 8 类面向对象的核心2 面向对象的程序设计本章主要内容 8.1 类初步 8.2 类的声明与定义 8.3 面向对象的设计思想 8.4 构造函数和析构函数 8.5 this指针 8.6 静态成员和常成员 8.7 在堆上创建类 8.8 友元8.1 类初步4 面向对象的程序设计一、从结构体到类回顾:通讯录程序struct Regist char name20;char gender;int age;char address100;需求:对一条记录进行修改,修改姓名,性别,年龄,地址等数据。5 面向对象的程序设计一、从结构体到类按照传统的解决方案,需要编写一个函数Void ChangeV

2、alue(Regist r, char *n, char s, int o, char *ad) strcpy(,n); r.sex=s; r.age=o;strcpy(r.address,ad);思考:Regist是数据,而ChangeValue是对数据的操作。从逻辑上考虑,它们的关系合理吗?6 面向对象的程序设计一、从结构体到类从逻辑上讲,“改变数据”是“记录”的功能,那么“改变”这个动作应该是“记录”这一数据类型的一部分。而在上面的实现中,它们的依存关系是相反的,而这也是典型的“面向过程”思想。设想:能不能把“改变数据”这个动作放到“记录”的内部呢?7 面向对象的程序设计一、

3、从结构体到类答案是肯定的,C+语言允许将一个函数放在结构体的内部,并且在这种情况下,函数可以直接访问结构体的成员,于是结构体变成:struct Regist char name20;char sex;int age;char address100;void ChangeValue (char *n, char s, int o, char *ad);8 面向对象的程序设计一、从结构体到类可以将这个设置函数直接定义在类的内部。进一步思考:对于一个实用的程序,在ChangeValue函数体内还必须进行更多的判断,例如检查姓名和地址是否超过范围,性别字符是否合法等。而上面的程序中,无法阻止结构体的使

4、用者“绕过” ChangeValue而直接操作成员数据。该如何解决呢?9 面向对象的程序设计一、从结构体到类C+语言提供的解决方法:设置访问权限struct Regist private:char name20;char gender;int age;char address100; public: void ChangeValue (char *n, char s, int o, char *ad);private:表示之后的数据外部无法访问public:表示之后的数据外部可以访问在结构体中,默认是public的示例示例110 面向对象的程序设计一、从结构体到类在这些变化之后,struct已

5、经远远超出了C语言中“结构体”的范畴,在C+语言中专门引入了一个新的关键字Class,这就是类。8.2 类的声明与定义12 面向对象的程序设计一、类的声明struct regist char name20;char sex;int age;char address100; void InputRegist();void SetRegist(char *n, char s, int a,char *d);void PrintRegist();类的声明格式:类的声明格式:class (struct) 类名类名 private : 成员数据成员数据;成员函数;成员函数; public : 成员数据成

6、员数据;成员函数;成员函数; protected:成员数据成员数据;成员函数;成员函数;;13 面向对象的程序设计类与对象l类是一个框架,说明了这种数据类型定义变量的组成方式l对象是类的一个实例变量,在内存中占据一定的空间l类声明了一种数据类型,对象类的变量l与结构体变量类似,使用取成员运算符.访问对象的成员变量与成员函数二、类和对象的作用域结构体类型结构体变量类类型类的变量类(Class)对象(Object)14 面向对象的程序设计二、类和对象的作用域类类型的作用域:l在函数定义之外定义的类,其类名的作用域为文件作用域;l而在函数体内定义的类,其类名的作用域为块作用域 对象的作用域与前面介绍

7、的变量作用域完全相同l全局对象l局部对象l动态对象等15 面向对象的程序设计三、成员函数将一个函数的声明放在类的说明,表示该函数属于这个类,是成员函数成员函数的定义可以在类内,但一般是定义在类的外部,定义形式如下:返回值类型返回值类型 类名类名 : 函数名函数名 (参数列表参数列表). /函数体函数体16 面向对象的程序设计成员函数使用同一个对象的其它成员时,可以直接使用(不用指出对象名)(包括函数成员)在类的成员函数中有三类不同作用域的变量l函数的内部变量,类的成员变量,文件的变量l逐层隐藏,也可以用域作用符:来指定一个类的所有对象,共享成员函数的代码,成员函数不占据各对象的空间三、成员函数

8、17 面向对象的程序设计四、成员的访问权限私有成员(用私有成员(用privateprivate说明的)说明的)l私有成员限定在该类的内部使用l私有的数据成员:只允许该类中的成员函数使用,l对于私有的成员函数:只能被该类内的成员函数调用;l类就相当于私有成员的作用域。 18 面向对象的程序设计公共成员:关键字publicl公有成员的数据或函数不受类的限制,可以在类内或类外自由使用;l对类而言是透明的保护成员:关键字protectedl允许在类内及该类的派生类中使用保护的数据或函数(到继承一章再讲)l保护成员的作用域是该类及该类的派生类一般我们会将类中的数据成员私有或保护,转而定义一些访问函数来操

9、作他们。四、成员的访问权限19 面向对象的程序设计class定义类,不特殊说明,成员是privatestruct定义类,不特殊说明,成员是public私有成员私有成员公有成员公有成员 保护成员保护成员类内类内可以调用可以调用可以调用可以调用 可以调用可以调用类外类外不可调用不可调用可以调用可以调用 不可调用不可调用四、成员的访问权限可见,在不考虑继承的情况下,私有和保护成员基本是一样的。20 面向对象的程序设计五、例子三角形学生成绩示例示例2与示例与示例38.3 面向对象的设计思想22 面向对象的程序设计一、面对对象的概念对象从程序的角度理解,是对结构体的一种延伸lObjectOriented

10、l将数据与对数据进行存在的过程结合在一起的一种程序要素l既有数据,又有函数软件开发中一种新的思想和丰富lOOAlOODlOOP23 面向对象的程序设计二、OOP的思想将代码和数据放到一个程序要素中,统一进行设计和管理由以函数为中心的设计以对象为中心的设计对象是第一位的,函数是属于对象的通过对象来调用函数,而不是过去将数据作为函数的参数有点:逻辑清晰,避免过多分支,减少函数数量24 面向对象的程序设计四、OO的特征封装性(Encapsulation)l特点l数据和方法的结合l数据具有隐蔽性(成员的类型),公共、私有、保护成员l目的l保护对象的数据,避免过分暴露;l数据使用更方便;l对使用者隐藏实

11、现的细节,使设计、实现和使用分开l前提是对类的抽象(abstract)l对对象的特征、行为的分析与概括l考虑:封装和继承l对类的整体思考25 面向对象的程序设计继承性(Inheritance)l从已有的类中通过增加新的成员的办法,产生的新的类l继承的方法:重复使用,增加,修改l基类(base class)和派生类(derived class)l单一继承和多重继承l形成一个类族26 面向对象的程序设计多态性(Polymorphsim)l同一个类族中不同的类,具有相同的方法,但是无论在功能还是实现上都上不同的l调用哪一个方法是由对象所决定的。8.4 构造函数和析构函数28 面向对象的程序设计一、对

12、象的建立用已经声明的类来定义一个变量时,就建立的该类的一个对象对象的生命周期和作用域与普通变量相同回忆:结构体变量如何初始化?strut student Wangqi=10001,”wangqi”,m,20,”JinZhou”;思考:类的变量对象如何初始化?29 面向对象的程序设计一、对象的建立鉴于类的复杂性,像结构体那样的直接初始化方式不能满足需求:l私有成员无法直接初始化l一些成员变量的初始值是通过一个过程计算得到的,无法直接指定值。l面向对象的复杂特性决定了不能直接初始化(继承和多态的存在)解决方法之一:定义一个赋值函数,把初始化过程包含在这个函数体中,但是必须显式调用,使用不便。并且这

13、种实现并非真正意义上的“初始化”(上一节中三角形的例子)30 面向对象的程序设计二、构造函数C+语言中的解决方法:构造函数(Constructor)类的特殊成员函数l名称:与类的名称相同l类型:无返值类型l调用:自动调用的时机:在建立对象调用,那么:l全局对象:在main函数执行前调用;l局部对象:对象定义时定义了构造函数之后,在建立对象时,通过给出不同的参数就可以自动调用,完成对象的构建。31 面向对象的程序设计二、构造函数class CDateint year,month,day;public:CDate(int y,int m,int d);CDate:CDate(int y,int m

14、,int d)year=y; month=m; day=d;/两种调用方式两种调用方式CDate day1(2011, 5, 1);CDate day2 = CDate(2011, 6, 1);构造函数的例子示例示例432 面向对象的程序设计二、构造函数可以通过重载的方式,构造多个参数不同的构造函数,用来以不同的方式初始化对象除了最普通的构造函数,还有几种常见的不同类型的构造函数示例示例533 面向对象的程序设计三、具有缺省参数值的构造函数与普通函数一样,构造函数可以声明参数的缺省值在函数声明中给出缺省值class CDate CDate(int y=2011,int m=5,int d=1)

15、;CDate day1;CDate day2(2010);CDate day3(2008,6);示例示例634 面向对象的程序设计四、初始化列表也可以不在构造函数中显式的赋值,而是在构造函数定义中的参数列表后加冒号,然后对成员逐个赋值,这一机制叫做初始化列表。列表中初始化的顺序是类定义时成员声明的顺序,而不是列表中的顺序初始化列表的效率很高,并且某些特殊的成员必须在这里得到值,而不能在函数体内赋值。CDate:CDate(int y, int m, int d): year(y), month(m), day(d) 35 面向对象的程序设计五、缺省的构造函数没有任何参数的构造函数当定义一个对象

16、切没给出任何参数值是自动调用该构造函数CClock: CClock()seconds=0;CClock clock1;一个缺省的构造函数,和一个全部参数值都要缺省值的构造函数不能同时存在如果没有任何构造函数,会自动生成一个缺省构造函数,如果已经定义了任何一个构造函数,就不会自动生成了。示例示例7;836 面向对象的程序设计六、拷贝构造函数构造函数的参数是同类的引用class X public:X(X&); 或 X(const X &);;用途:l用一个同类对象来初始化为什么要使用引用?用一个对象“初始化出一个相同的对象”,与建立一个新对象再赋值其意义是不同的。如果没有定义拷贝构

17、造函数,编译系统会自动生成一个。进行逐对成员的赋值(byte-wise)示例示例937 面向对象的程序设计六、拷贝构造函数思考:在什么情况下自动生成的拷贝构造函数会失效?示例示例1038 面向对象的程序设计七、析构函数(Destructor)思考:下面的程序在构造函数中用malloc分配了一段内存,如果这个类离开作用域之后便消失了,这段分配的内存会怎样呢?class chunkvoid *p;public:chunk(int n) p =malloc(n);chunk c;/作用域结束了作用域结束了c被自动销毁被自动销毁39 面向对象的程序设计七、析构函数(Destructor)结果是:c消失

18、了,但是malloc分配的内存还存在,但却不能使用了,因为指针p已经和对象c一起消失了,造成内存泄漏(memery leak)。解决方法之一是为chunk类编写一个专门释放内存的函数,但这就要求在chunk的对象被销毁之前调用这个函数,在程序中无疑这是不可能做到的。40 面向对象的程序设计七、析构函数(Destructor)C+中提供的解决方法:析构函数(Destructor)类的特殊成员函数l名称:类的名称前加 l类型:无返值类型,无参数l调用:自动,在对象销毁时由系统自动调用l不能重载作用:清理现场,如释放动态分配的内存41 面向对象的程序设计七、析构函数(Destructor)Chunk

19、类变为:class chunkvoid *p;public:chunk(int n) p =malloc(n);chunk() free(p);示例示例1142 面向对象的程序设计 八、对象嵌套一个类的成员是另外一个类的对象(参考:结构体的成员可以是另一个结构体变量)除非作为成员类的成员有默认构造函数,否则必须在初始化列表中对其初始化。class Pointint x,y;public: Point(int xi,int yi):x(xi),y(yi);class Circle Point center;int radia;Circle(int m,int n,intr) :center(m,

20、n),radia(r) ;能否用 x(m), y(n)替代 center(m,n)?示例示例1243 面向对象的程序设计九、对象数组对象数组的说明与一般数组说明一样对象数组的初始化l除非有一个缺省构造函数,否则必须全部初始化这个数组class Pointint x,y;public: Point(int x,int y);Point pt4= Point(1,1),Point(2,1),Point(1,2),Point(2,2);示例示例128.5 This指针45 面向对象的程序设计this指针l每个成员函数都有一个隐参数,由编译系统自动生成、传递,这个参数就是指向对象本身的指针,名称是”t

21、his”.l在成员函数中可以直接使用这个指针l例如某个类的中有成员变量age,在成员函数中使用age时,即可以直接写age,也可以写成this-age,表明age是本类的成员,看起来更清晰示例示例138.6 静态成员与常成员47 面向对象的程序设计一、静态数据成员一个成员的类型是static,这一成员就是静态成员静态成员一个类只有一个,被类中的所有成员共有,类定义后就存在静态成员需要在类内声明,类外定义48 面向对象的程序设计一、静态数据成员class Astatic int i;public:A();int A:i=0;这一做法看上去不太合理,因为它在类外操作了一个私有成员,但是C+的语言机

22、制可以保证安全性,因为静态成员必须有定义而且只能定义一次,这就有效的阻止了对静态私有成员的随意访问。示例示例1449 面向对象的程序设计一、静态数据成员访问方法l用类名:l用对象名或对象指针用途:存放属于“类”的信息,最典型的用途就是对象计数器,用来记录这个类的对象的个数示例示例1550 面向对象的程序设计二、静态函数成员只允许存取静态数据成员,调用其他静态函数成员。没有隐参数this示例示例1651 面向对象的程序设计如果一个成员变量被说明为常量,称为常量成员变量如果类里有常量成员,必须在初始化列表中列表中初始化三、常对象和常量成员52 面向对象的程序设计三、常对象和常量成员被说明为常量的对

23、象:const clock c(12,0,0);int val() const return dada;常量成员函数不能更改任何成员变量,也不能调用非常量成员函数一个对象是一个常量对象时,它的成员函数将不能被调用,因为可能存在潜在的改变,除非这个函数也是一个常量成员函数53 面向对象的程序设计实际上,关于静态成员和常量成员,还有许多复杂的话题,如静态成员数组,以及static与const关键字的联用等,本课程中不作要求,但建议大家课下进行学习。三、常对象和常量成员8.7 在堆上创建类55 面向对象的程序设计一、堆内存的使用回忆:C+程序的内存布局l全局数据区(data area):存放全局变量

24、、静态数据、常量。l代码区(code area):存放类成员函数、其他函数代码。 l栈区(stack area):存放局部变量、函数参数、返回数据、返回地址。l堆区 (heap area):自由存储区。 56 面向对象的程序设计一、堆内存的使用回忆:什么情况下需要用到堆回忆:如何使用堆内存回忆:在堆上分配的内存有什么特点57 面向对象的程序设计一、堆内存的使用什么情况下需要用到堆l大块内存,比如很大的数组l按需分配的内存,比如无法预估长度的数组/链表如何使用堆内存lC语言中使用malloc/free函数解决在堆上分配的内存有什么特点l手动分配,手动释放58 面向对象的程序设计一、堆内存的使用类

25、似地,可以将类的对象分配在堆上,对于大体积的对象,动态的对象尤其如此思考:用malloc建立动态对象会存在哪些不便?示例示例1759 面向对象的程序设计一、堆内存的使用缺点:l只按照字节数分配内存,需要根据不同的类型进行计算l分配后的指针 void *, 必须强制转换l不能调用构造函数直接初始化类C+ 的解决方案:new/delete 运算符运算符60 面向对象的程序设计二、new运算符根据给出对象的数量动态分配对象,自动计算需要的空间直接返回该类型的指针同时根据初始的参数调用相应的构造函数格式:type * p = new type(构造函数的实参列表);type * p = new type个数;type 可以是基本类型 也可以是类61 面向对象的程序设计二、new运算符用new运算符动态建立对象int *p1=new int; int *p2= new int(10);CDate *pc1=new CDate; /调用缺省构造函数CDate *pc2=new CDate(2011,5,10);/调用另一个构造函数62 面向对象的程序设计二、new运算符用new运算符动态建立对象数组int *p3= new int10;CDate *pc3=new CDa

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论