当前位置首页 > 高等教育 > 大学课件/教案
搜柄,搜必应! 快速导航 | 使用教程  [会员中心]

天津大学C类和对象

文档格式:PPTX| 109 页|大小 742.56KB|积分 20|2024-03-26 发布|文档ID:240270080
第1页
下载文档到电脑,查找使用更方便 还剩页未读,继续阅读>>
1 / 109
此文档下载收益归作者所有 下载文档
  • 版权提示
  • 文本预览
  • 常见问题
  • 会计学1天津大学天津大学C 类和对象类和对象本章内容本章内容n n面向对象程序设计概述面向对象程序设计概述n n类的定义类的定义n n对象的定义和对象成员的引用对象的定义和对象成员的引用n n构造函数构造函数n n析构函数析构函数n n类的组合类的组合n nthisthis指针指针n n静态成员静态成员n n友元友元n n类模板类模板第1页/共109页程序设计方法的发展历程程序设计方法的发展历程n n面向过程的程序设计方法 SP(Structured Programming)n n面向对象的程序设计 OOP(Object Oriented Programming)towardsin relation to concerning第2页/共109页面向过程的程序设计方法面向过程的程序设计方法n n重点重点 以功能为中心以功能为中心 ,采用函数来描述,数据与函数分采用函数来描述,数据与函数分开,如何实现细节过程开,如何实现细节过程n n设计思路特点设计思路特点 自顶向下,逐步求精自顶向下,逐步求精功能分解功能分解n n程序结构形式程序结构形式 主模块主模块+若干个子模块(若干个子模块(main()+main()+子函数)。

    每子函数)每 一模块内部均是由顺序、选择和循环三种基本一模块内部均是由顺序、选择和循环三种基本 结构组成结构组成n n缺点缺点 效率低,程序的可重用性差效率低,程序的可重用性差第3页/共109页面向过程结构化程序设计第4页/共109页面向过程结构化程序设计数据1数据2数据3第5页/共109页7两种程序设计方法面向过程的 面向对象的程序设计程序设计 (OOP)FUNCTION1FUNCTION2FUNCTION3OBJECT3Operations DataOBJECT2Operations DataOBJECT1Operations Datadata3data2data1第6页/共109页面向对象的程序设计方法面向对象的程序设计方法n n观点:观点:客观世界是由各种各样的实体(对象)组成的客观世界是由各种各样的实体(对象)组成的n n程序设计方法:程序设计方法:使用面向对象的观点来描述模仿并处理现实问题使用面向对象的观点来描述模仿并处理现实问题使程序设计方法更符合人类的思维方式,更使程序设计方法更符合人类的思维方式,更直接地描述客观世界直接地描述客观世界n n要求:要求:高度概括、分类、和抽象。

    高度概括、分类、和抽象n n目的:目的:通过提高代码的可重用性、可扩充性来提高编程通过提高代码的可重用性、可扩充性来提高编程效率,大大减少软件维护的开销适合于大程效率,大大减少软件维护的开销适合于大程序的开发工作序的开发工作 第7页/共109页ATM-结构化设计结构化设计输入密码插卡验证密码和帐号是由有效的选择取现金输入数目改变余额现金输出打印收条退卡按照结构化设计的方法从ATM中取款,其中时间顺序表明我们关心的是用户按照怎样的步骤来完成取款操作第8页/共109页读卡得到密码联系银行进行验证得到选项和数目发钱打印收条插卡输入密码选择取现金输入数目取钱取收条取卡采用面向对象方法的采用面向对象方法的ATM改变帐号和密码检查余额调整余额银行客户 银行ATM对象类操作KellyJoneCorner ATMC+Bank 第9页/共109页比较n nBefore OOPBefore OOPn n代码联系紧密代码联系紧密代码联系紧密代码联系紧密n n难于编写和维护难于编写和维护难于编写和维护难于编写和维护n n难于修改难于修改难于修改难于修改n n代码可重用性差代码可重用性差代码可重用性差代码可重用性差n n数据安全性不好数据安全性不好数据安全性不好数据安全性不好n n小型软件开发效率小型软件开发效率小型软件开发效率小型软件开发效率高高高高n nWith OOPWith OOPn n程序是由一系列相程序是由一系列相程序是由一系列相程序是由一系列相互协作的对象构成互协作的对象构成互协作的对象构成互协作的对象构成n n更易于编写和维护更易于编写和维护更易于编写和维护更易于编写和维护n n修改容易修改容易修改容易修改容易n n代码可重用性高代码可重用性高代码可重用性高代码可重用性高n n数据安全性好数据安全性好数据安全性好数据安全性好n n开发大型软件和图开发大型软件和图开发大型软件和图开发大型软件和图形界面的应用软件形界面的应用软件形界面的应用软件形界面的应用软件效率高效率高效率高效率高第10页/共109页对象对象一般意义上的对象:是现实世界中一个实际存在的事物。

    可以是有形的(比如一辆汽车),也可以是无形的(比如一项计划)是构成世界的一个独立单位,具有:n n静态特征:对象具有的对象具有的状态状态(state state),可以),可以用用 某种数据来描述某种数据来描述n n动态特征:对象所表现的对象所表现的行为行为(behavior/actionbehavior/action)或具有的或具有的功能功能第11页/共109页思考思考n nWhat would a MP3 player object be like?n n属性(属性(DataData):n n行为(行为(ActionsActions):第12页/共109页思考思考n nWhat would a MP3 player object be like?n n属性(属性(DataData):n nnumber of songsnumber of songsn ncurrent songcurrent songn npower levelpower leveln nsongs songs n n行为(行为(A Actionsctions):n nplayplayn npausepausen nrewindrewindn nforwardforwardn non/offon/off第13页/共109页对象对象面向对象方法中的对象:是系统中用来描述客观事物的一个实体,它是用来构成系统的一个基本单位。

    对象由一组属性和一组行为构成n n属性:用来描述对象静态特征的数据项n n行为:用来描述对象动态特征的操作序列第14页/共109页对象对象现实世界现实世界现实世界现实世界对象:现实世界中一个对象:现实世界中一个对象:现实世界中一个对象:现实世界中一个 实际存在的事物实际存在的事物实际存在的事物实际存在的事物静态特征:对象具有的状态静态特征:对象具有的状态静态特征:对象具有的状态静态特征:对象具有的状态动态特征:对象所表现的动态特征:对象所表现的动态特征:对象所表现的动态特征:对象所表现的 行为或具有的功能行为或具有的功能行为或具有的功能行为或具有的功能计算机世界对象:类的一个实例(变量)静态特征:数据成员动态特征:方法(由一组函数定义)对象方法数据对象=数据+作用于这些数据上的操作 =属性+方法(由一组函数定义)第15页/共109页对象 人n n属性:属性:char*name,char*gender,int char*name,char*gender,int age,int idage,int idn n行为行为:getCloth(),eat(),step,work()getCloth(),eat(),step,work()第16页/共109页类类n n分类 人类通常的思维方法n n分类所依据的原则 抽象n n忽略事物的非本质特征,只注意那些与当前目忽略事物的非本质特征,只注意那些与当前目标有关的本质特征,从而找出事物的共性,把标有关的本质特征,从而找出事物的共性,把具有共同性质的事物划分为一类,得出一个抽具有共同性质的事物划分为一类,得出一个抽象的概念。

    象的概念第17页/共109页面向对象方法中的面向对象方法中的“类类”n n为属于该类的全部对象提供了统一的抽象描述,包括属性和行为两个主要部分n n类定义了这一类对象所共有的特征和行为n n类不是具有相同属性和操作的一组对象的集合TorpiePerson抽象定义 AllenMeijer第18页/共109页抽象实例人类J ClarkPerson-name-gender-age-id+getCloth()+eat()+step()+work()类名方法属性第19页/共109页类(classes)与对象(objects)的关系?n nObject:Object:数据和行为的逻辑组合n nClass:Class:对象的定义或对象的蓝图(blue print)n nInstance:Instance:从类中创建的一个变量第20页/共109页类与对象的关系类与对象的关系类名属性方法对象对象的完整定义每个对象都视为该类的一个实例(instance)类是抽象的,对象是具体的类是模型,对象是实例类是类型,对象是变量第21页/共109页面向对象程序设计方法面向对象程序设计方法问题现实世界计算机世界(程序)对象间发消息并作出响应l对象:现实中存在的任何一个事物。

    有两种特征:静态特征:属性动态特征:行为对象1对象n概念1概念m类1类m对象1对象nl类:同类对象的抽象描述,C+中的一种自定义类型静态特征:数据成员动态特征:函数成员l概念:同类对象的抽象描述l对象:类的一个实例(变量)第22页/共109页面向对象程序设计方法的基本特征面向对象程序设计方法的基本特征n n抽象性 n n封装性n n继承性n n多态性第23页/共109页面向对象的程序设计方法面向对象的程序设计方法n n将数据及对数据的操作方法封装封装在一起,作为一个相互依存、不可分离的整体 对象对象n n对同类型对象抽象抽象出其共性,形成类类n n类通过一个简单的外部接口,与外界发生关系n n对象与对象之间通过发消息进行通讯n n通过类的继承继承与多态多态实现代码重用第24页/共109页 面向对象语言的特点 封装性(信息隐藏)封装性(信息隐藏)n n把对象的属性和服务结合成一个独立的系把对象的属性和服务结合成一个独立的系统单元n n尽可能隐蔽对象的内部细节对外形成一尽可能隐蔽对象的内部细节对外形成一个边界(或者说一道屏障),只保留有限个边界(或者说一道屏障),只保留有限的对外接口使之与外部发生联系。

    的对外接口使之与外部发生联系第25页/共109页面向对象语言的特点 继承性继承性n n继承对于软件复用有着重要意义,是面向继承对于软件复用有着重要意义,是面向对象技术能够提高软件开发效率的重要原对象技术能够提高软件开发效率的重要原因之一n n派生类对象派生类对象“自动地拥有自动地拥有”父类的全部属父类的全部属性与行为性与行为n n例如:将轮船作为一个父类,客轮便是一例如:将轮船作为一个父类,客轮便是一个派生类(子类)个派生类(子类)第26页/共109页面向对象语言的特点 多态性多态性n n在父类中定义的属性或行为,被派生类继在父类中定义的属性或行为,被派生类继承之后,可以具有不同的数据类型或表现承之后,可以具有不同的数据类型或表现出不同的行为特性出不同的行为特性n n例如:例如:数的加法数的加法数的加法数的加法-实数的加法实数的加法实数的加法实数的加法 -复数的加法复数的加法复数的加法复数的加法第27页/共109页类的定义类的定义类类声明形式:声明形式:class class 类名称类名称 public:public:公有成员(外部接口)公有成员(外部接口)private:private:私有成员私有成员 protected:protected:保护型成员保护型成员;访问权限 私有成员只能被本类中的函数访问而类外部的任何函数都不能访问。

    公有成员作为对外的接口,任何外部函数都可以访问公有类型数据和函数保护成员与private类似,其差别表现在继承与派生时对派生类的影响不同第28页/共109页矩形类的定义矩形类的定义class Rectclass Rectpublic:public:void setXY(float x1,float y1);void setXY(float x1,float y1);/成员函数原型说明成员函数原型说明成员函数原型说明成员函数原型说明 float getX()return x;float getX()return x;/取得长取得长取得长取得长 float getY()return y;float getY()return y;/取到宽取到宽取到宽取到宽 float area();float area();/成员函数原型说明成员函数原型说明成员函数原型说明成员函数原型说明private:private:float x,y;float x,y;/矩形的长和宽矩形的长和宽矩形的长和宽矩形的长和宽;void Rect:setXY(float x1,float y1)void Rect:setXY(float x1,float y1)x=x1;x=x1;y=y1;y=y1;float Rect:area()return x*y;float Rect:area()return x*y;成员函数数据成员内联成员函数定义第29页/共109页class Rectclass Rectpublic:public:void setXY(float x1,float y1);void setXY(float x1,float y1);/成员函数原型说明成员函数原型说明成员函数原型说明成员函数原型说明 float getX()return x;float getX()return x;/内联成员函数定义内联成员函数定义内联成员函数定义内联成员函数定义 float getY()return y;float getY()return y;/内联成员函数定义内联成员函数定义内联成员函数定义内联成员函数定义 float area();float area();/成员函数原型说明成员函数原型说明成员函数原型说明成员函数原型说明private:private:float x,y;float x,y;inline void Rect:setXY(float x1,float y1)inline void Rect:setXY(float x1,float y1)x=x1;x=x1;y=y1;y=y1;float Rect:area()return x*y;float Rect:area()return x*y;矩形类的定义矩形类的定义成员函数数据成员第30页/共109页数据成员数据成员与一般的变量声明相同,但需要将它放在类的声明体中。

    第31页/共109页成员函数成员函数n n类的成员函数的定义可以在类体内也可以在类体外,若在体外,需在函数名前加类名和作用域分辨符:加以限定n n在类体内定义的成员函数将被自动处理为内联函数无需加关键字inline,而要使得在类体外定义的成员函数成为内联函数时,就必须使用inline关键字第32页/共109页讨论讨论n n通常把类的数据成员定义为私有,并通过公有成员函数(接口函数)对它们进行访问n n定义类的私有成员可实现数据隐藏,而数据隐藏对维护对象的完整性是必不可少的n n接口函数可以把对数据的存储细节与数据的使用细节分开第33页/共109页我们可以控制数据的存取成员函数n n是是 publicpublicn n用于使类外用户访问私有数据用于使类外用户访问私有数据成员成员xygetYsetXYareagetX第34页/共109页对象的定义对象的定义n n对象 类是一种用户自定义的数据类型,这种数据类是一种用户自定义的数据类型,这种数据类型的变量称为该类的对象类型的变量称为该类的对象n n对象的定义格式:类名 对象名表;例:Rect ob1;/ob1是 Rect类的对象第35页/共109页对象成员的引用对象成员的引用n n类内,类成员可以由类的所有成员函数直接访问。

    n n直接使用成员名直接使用成员名n n类外n n使用使用“对象名对象名.成员名成员名”方式访问方式访问 publicpublic 属性的属性的成员成员n n如,如,ob1.area();ob1.area();n n.称为成员选择运算符称为成员选择运算符第36页/共109页 矩形类及其对象的使用class Rectpublic:void setXY(float x1,float y1)x=x1;y=y1;float area()return x*y;float getX()return x;float getY()return y;private:float x,y;int main()Rect r1;/定义矩形类 Rect对象 r1.setXY(12.5,20);/若写r1.x=12.5则错误!cout r1.area()endl;return 0;第37页/共109页 面向对象语言的特点 封装性(信息隐藏)封装性(信息隐藏)n n把对象的属性和服务结合,构成一个不可分割的整体把对象的属性和服务结合,构成一个不可分割的整体把对象的属性和服务结合,构成一个不可分割的整体把对象的属性和服务结合,构成一个不可分割的整体n n在这个整体中一些成员是私有的(或保护的),尽可在这个整体中一些成员是私有的(或保护的),尽可在这个整体中一些成员是私有的(或保护的),尽可在这个整体中一些成员是私有的(或保护的),尽可能隐蔽对象的内部细节,以防外界的干扰和误操作。

    能隐蔽对象的内部细节,以防外界的干扰和误操作能隐蔽对象的内部细节,以防外界的干扰和误操作能隐蔽对象的内部细节,以防外界的干扰和误操作n n在这个整体中一些成员是在这个整体中一些成员是在这个整体中一些成员是在这个整体中一些成员是 公有的,它们作为接口提供公有的,它们作为接口提供公有的,它们作为接口提供公有的,它们作为接口提供 给外界使用给外界使用给外界使用给外界使用第38页/共109页 矩形类及其对象的使用class Rectpublic:void setXY(float x1,float y1)x=x10?0:x1;y=y10?0:y1;float area()return x*y;float getX()return x;float getY()return y;private:float x,y;int main()Rect r1;r1.setXY(-12.5,-20);cout r1.area()area()pd-area()对象引用名对象引用名.公有数据成员名公有数据成员名 对象引用名对象引用名.公有成员函数名公有成员函数名(实参表实参表)rd1.area()rd1.area()第42页/共109页 矩形类及其对象的使用class Rectpublic:void setXY(float x1,float y1)x=x1;y=y1;float area()return x*y;float getX()return x;float getY()return y;private:float x,y;int main()Rect r1,r2;r1.setXY(12.5,20);cout r1.area()endl;cout r2.area()endl;/有问题 return 0;第43页/共109页 构造函数 举例 class Rectpublic:Rect(float x1,float y1)x=x1;y=y1;void setXY(float x1,float y1)x=x1;y=y1;float area()return x*y;private:float x,y;int main()Rect r1(12.5,20);/调用构造函数将x,y初始化为12.5和50 cout r1.area()endl;r1.setXY(5.2,6.8);/调用setXY成员函数重新设置x,y的值 cout r1.area()endl;return 0;第44页/共109页构造函数构造函数构造函数构造函数构造函数 构造函数是类的特殊成员构造函数是类的特殊成员函数。

    用于对对象的私有数据成函数用于对对象的私有数据成员进行员进行初始化初始化构造函数的特点是:构造函数名必须和本类类名相同;构造函数不允许有任何返回类型,void也不能有;构造函数的参数个数可以为0,也可以有多个,故构造函数可以重载;遇到对象定义时自动调用构造函数;每个类至少有一个构造函数第45页/共109页构造函数构造函数n nC+C+规定,如果一个类没有提供任何的构造函规定,如果一个类没有提供任何的构造函数,则数,则C+C+提供一个默认的构造函数(由提供一个默认的构造函数(由C+C+编译器提供),这个默认的构造函数是一个不编译器提供),这个默认的构造函数是一个不带参数的构造函数,它不做任何的初始化工作带参数的构造函数,它不做任何的初始化工作n n只要一个类定义了一个构造函数,不管这个构只要一个类定义了一个构造函数,不管这个构造函数是否是带参数的构造函数,造函数是否是带参数的构造函数,C+C+就不再就不再提供默认的构造函数也就是说,如果为一个提供默认的构造函数也就是说,如果为一个类定义了一个带参数的构造函数,还想要无参类定义了一个带参数的构造函数,还想要无参数的构造函数,则必须自己定义数的构造函数,则必须自己定义。

    第46页/共109页 构造函数 举例 class Rectpublic:Rect(float x1,float y1)x=x1;y=y1;void setXY(float x1,float y1)x=x1;y=y1;float area()return x*y;private:float x,y;int main()Rect r1(12.5,20);/调用构造函数将x,y初始化为12.5和50 cout r1.area()endl;Rect r2;/调用Rect(),出错 cout r2.area()endl;return 0;第47页/共109页 构造函数 重载 class Rectpublic:Rect(float x1,float y1)x=x1;y=y1;Rect()x=5;y=3;void setXY(float x1,float y1)x=x1;y=y1;float area()return x*y;private:float x,y;int main()Rect r1(12.5,20);/调用构造函数将x,y初始化为12.5和50 cout r1.area()endl;Rect r2;/调用Rect(),出错 cout r2.area()endl;return 0;第48页/共109页 构造函数 举例 class Rectpublic:Rect()x=5;y=3;void setXY(float x1,float y1)x=x1;y=y1;float area()return x*y;private:float x,y;int main()Rect r1,r2;/调用构造函数后r1、r2一样 r1.setXY(12.5,20);r2.setXY(22.5,10);cout r2.area()endl;return 0;第49页/共109页构造函数的重载classDatepublic:/需要几个构造函数?voidprint();private:intyear,month,day;voidDate:print()coutyear“.”month“.”dayendl;voidmain()Date d1;Date d2(2010);Date d3(2010,5);Date d4(2010,4,28);第50页/共109页在构造函数中使用默认参数classDatepublic:Date()year=2008;month=4;day=1;Date(inty,intm=1,intd=1)year=y;month=m;day=d;Date(inty,intm,intd=1)year=y;month=m;day=d;Date(inty,intm,intd)year=y;month=m;day=d;private:intyear,month,day;voidmain()Dated1;Dated2(2007);Dated3(2007,5);Dated4(2007,4,28);第51页/共109页在构造函数中使用默认参数classDatepublic:Date(inty=2000,intm=1,intd=1);/默认构造函数voidprint();private:intyear,month,day;Date:Date(inty,intm,intd)year=y;month=m;day=d;voidDate:print()coutyear“.”month“.”day=1900&y=1&m=1&d=31)?d:1;voidDate:print()coutyear“.”month“.”dayendl;voidmain()Dated1;Dated2(2007);Dated3(2007,5);Dated4(2008,4,28);d1.print();d2.print();d3.print();d4.print();第53页/共109页classDatepublic:Date();Date(inty,intm,intd);voidprint();private:intyear,month,day;Date:Date(inty,intm,intd):year(y),month(m),day(d)Date:Date():year(2008),month(1),day(1)voidDate:print()coutyear“.”month“.”dayendl;voidmain()Dated1;/调用Date();Dated2(2008,7,1);/调用Date(int,int,int)d1.print();d2.print();数据成员初始化表第54页/共109页第55页/共109页关于构造函数的讨论关于构造函数的讨论n n构造函数的作用就是初始化对象n n没有形参或形参都有缺省值的构造函数称为默认构造函数n n构造函数由系统在创建对象时自动调用 调用时机为:n n遇到对象定义时自动调用合适的遇到对象定义时自动调用合适的构造函数构造函数 n n遇到遇到 new new 类名类名 或或 new new 类名类名 长度长度 时自动调用默认构造函数时自动调用默认构造函数 n n构造函数应定义为公有成员第56页/共109页voidmain()Dated1;/调用Date();Dated2(2007,7,1);/调用Date(int,int,int)Dated35;/调用5次 Date();Date*p1,*p2;/不调用构造函数p1=newDate(2007,11,27);/调用Date(int,int,int)p2=newDate4;/调用四次Date();第57页/共109页析构函数析构函数析构函数 析构函数是类的特殊成员函数。

    完成对象被释放前的一些清理工作析构函数的特点是:析构函数名为本类类名前加一个“”符号析构函数不允许有任何返回类型析构函数不允许带参数一个类中只能有一个析构函数,即不能重载析构函数如果程序中未定义析构函数,编译程序将自动提供一个函数体为空的默认析构函数第58页/共109页什么时候调析构函数?什么时候调析构函数?n n在对象的生存期结束时,自动调用析构函数第59页/共109页intmain()Dated1;Dated2(2007,7,1);return0;调用析构函数析构函数的调用第60页/共109页 析构函数的调用顺序通常是与构造函数的调用顺序相反的即先构造的后析构,后构造的先析构要注意,对象的生存期会改变析构函数的调用顺序构造函数和析构函数第61页/共109页intmain()Dated1;Dated2(2007,7,1);p1=newDate(2007,11,27);p2=newDate4;deletep1;/调用析构函数deletep2;/调用析构函数return0;调用析构函数析构函数的调用第62页/共109页例:计算两点间距离运行class Point double x,y;public:Point(double a=0,double b=0)x=a;y=b;cout 构造点(x,y )n;void print()cout 点(x,y );double distance(Point&pr)double dx,dy;dx=x-pr.x;dy=y-pr.y;return sqrt(dx*dx+dy*dy);Point()cout 析构点(x ,y )n;int main()Point ob1,ob2(-3,4);ob1.print();cout 到;ob2.print();cout 的距离=;cout ob1.distance(ob2);cout endl;return 0;第63页/共109页 运行class Product char *name;float price;public:Product(char*n,float p);Product();void print()cout name priceendl;Product:Product(char*n,float p)name=new char strlen(n)+1;strcpy(name,n);price=p;cout 调用构造函数 endl;Product:Product()if(name)delete name;name=0;cout 调用析构函数 endl;int main()Product p1(电视机,2350);p1.print();return 0;例:析构函数应用举例。

    调用构造函数电视机 2350调用析构函数程序运行结果:第64页/共109页思考思考we have the following code:we have the following code:Product:Product(char*n,float p)name=new char strlen(n)+1;strcpy(name,n);price=p;Q:What happens when the Q:What happens when the main main function finishes?function finishes?name 电视机02350price p1 Product p1(电视机,2350);第65页/共109页思考思考Q:Q:如果没有定义析构函数,当主函数完成后会发生什么?A:A:变量变量namename 被释放被释放,因此不能访问动态内存,造成动因此不能访问动态内存,造成动态内存泄露态内存泄露Memory Leak内存泄露name 电视机0price p1 第66页/共109页思考思考 定义一个析构函数,释放动态内存空间定义一个析构函数,释放动态内存空间Product:Product()Product:Product()if(name)if(name)delete name;delete name;/释放动态内存空间释放动态内存空间 name=0;name=0;23500Memory is given backname 电视机0price p1 第67页/共109页思考思考void main()Product p1(“电视机”,2350);p1.Print();析构函数被自动调用Memory is given backname 电视机0price p1 第68页/共109页关于析构函数的说明关于析构函数的说明n n析构函数的作用正好与构造函数相反,在对象生存期结束时自动调用析构函数。

    n n如果在构造函数中用new运算符为对象的成员分配了内存空间(堆内存),应该在类中定义析构函数,用delete释放申请的空间,否则,可能会出现内存泄漏n n若用户没有定义析构函数,编译程序将自动生成一个函数体为空的析构函数第69页/共109页问题2:在前例中name可否不用动态内存分配直接使用指针?name price p1 2350ps TV Set0第70页/共109页问题3:在前例中可否不用动态内存分配,用字符数组来实现?ps name price p1 TV Set0TV Set02350第71页/共109页拷贝构造函数拷贝构造函数拷贝构造函数拷贝构造函数 是一种特殊的构造函数,其形参为本是一种特殊的构造函数,其形参为本 类的对象引用类的对象引用作用作用:用一个已定义的对象初始化一个被创建的同类用一个已定义的对象初始化一个被创建的同类 对象对象 class class 类名类名 public:public:类名(形参);类名(形参);/构造函数构造函数 类名(类名类名(类名&对象名);对象名);/拷贝构造函数拷贝构造函数 .;第72页/共109页拷贝构造函数如果程序员没有为类定义拷如果程序员没有为类定义拷贝构造函数,则编译器自己生成贝构造函数,则编译器自己生成一个默认的拷贝构造函数。

    一个默认的拷贝构造函数这个构造函数的功能是:把这个构造函数的功能是:把已定义对象的每个数据成员的值已定义对象的每个数据成员的值复制给新创建对象的对应数据成复制给新创建对象的对应数据成员即实现数据成员的复制即实现数据成员的复制第73页/共109页拷贝构造函数拷贝构造函数由系统自动调用拷贝构造函数由系统自动调用拷贝构造函数由系统自动调用拷贝构造函数由系统自动调用拷贝构造函数的调用时机拷贝构造函数的调用时机拷贝构造函数的调用时机拷贝构造函数的调用时机:n n用一个已定义的对象初始化一个新用一个已定义的对象初始化一个新的同类对象的同类对象n n在调用一个函数时在调用一个函数时,把对象作为函把对象作为函数实参传递给函数形参数实参传递给函数形参n n对象作为函数返回值对象作为函数返回值第74页/共109页拷贝构造函数用一个已定义的对象初始化一个新用一个已定义的对象初始化一个新的同类对象的同类对象classPointprivate:floatx,y;/点的坐标public:Point(floatx1=0,floaty1=0)x=x1;y=y1;voidmain()Pointp1(5,6);Pointp2(p1);/用p1初始化p2系统提供的拷贝构造函数Point(constPoint&p)x=p.x;y=p.y;调拷贝构造函数第75页/共109页拷贝构造函数 当对象作为一个函数实参传递给函数形参当对象作为一个函数实参传递给函数形参当对象作为一个函数实参传递给函数形参当对象作为一个函数实参传递给函数形参(值传递)值传递)值传递)值传递)当对象作为函数返回值当对象作为函数返回值当对象作为函数返回值当对象作为函数返回值Point fun(Point p):return p;/用p初始化匿名对象void main()Point p1(5,6),p2;p2=fun(p1);/用p1初始化形参px:5y:6x:5y:6p匿名p1x:5y:6x:5y:6p调用Point(p1);调用Point(p);第76页/共109页this指针this指针是一个隐含于每个类的成员函数中的特殊指针。

    它指向当前调用成员函数的对象(称为当前对象)代表了当前对象的地址第77页/共109页this指针classTestintx;public:Test(inta=0)x=a;voidprint()coutxendl;intmain()Testt1(12),t2(20);t1.print();t2.print();return0;voidprint(Test*this)coutx例如:cout x endl;等价于 cout x endl;第79页/共109页this指针classTestintx;public:Test(inta=0)x=a;voidprint()coutxendl;intmain()Testt1(12);t1.print();return0;voidprint()/this指向t1coutxendl;voidprint()/this指向t1cout(*this).xendl;第80页/共109页#include class Test int x;public:Test&Setx(int a=0)x=a;return*this;Test&Print()coutx=x3 3 attackattack=2=2 retrearetreat t第87页/共109页静态成员静态数据成员静态数据成员必须在类体内说明,并且必须在类体和函数之外定义一次。

    静态数据成员的说明:static类型名 静态数据成员名;(类体内)静态数据成员的定义:类型 类名:静态数据成员;/缺省初始值为0 类型 类名:静态数据成员=初始值;(类体外)第88页/共109页例:静态数据成员的使用示例记录对象的个数程序运行结果:class counter private:int objno;/对象序号 static int count;/静态数据成员,对象计数器public:counter()count+;/每创建一个对象,对象数加1 objno=count;/设置当前对象序号值 counter()count-;void show()cout count=count show();delete pc;obj1.show();return 0;count=1 count=2 count=1第89页/共109页静态成员函数静态成员函数静态成员函数没有this指针一般使用静态成员函数来访问静态数据成员若需要在静态成员函数中访问非静态数据成员,则要使用对象参数静态成员函数的定义:只需在成员函数前加 static 对公有的静态成员函数,可用以下形式调用:对象名.静态成员函数名(实参表)类名:静态成员函数名(实参表)第90页/共109页例:静态成员函数的使用示例。

    记录对象的个数count=0 count=1 count=2 count=1程序运行结果:第91页/共109页例:静态成员函数的使用示例记录对象的个数程序运行结果:class counterprivate:int objno;/对象序号 static int count;/静态数据成员说明public:counter()count+;objno=count;counter()count-;static void show()cout count=count show()?/obj1.show()?delete pc;counter:show();return 0;count=0 count=1 count=2 count=1第92页/共109页例:静态成员函数的使用示例记录对象的个数count=1objno=1程序运行结果:第93页/共109页友元友元n n友元是C+提供的一种破坏数据封装和数据隐藏的机制n n通过将一个模块声明为另一个模块的友元,一个模块能够引用到另一个模块中本是被隐藏的信息n n可以使用友元函数和友元类n n为了确保数据的完整性,及数据封装与隐藏的原则,建议尽量不使用或少使用友元。

    第94页/共109页友元函数友元函数n n友元函数是在类声明中由关键字friend修饰说明的非成员函数(可可以是一个普通函数,也可以是其以是一个普通函数,也可以是其他类的一个成员函数他类的一个成员函数)n n类的友元函数只能通过该类的对象访问该类的私有(private)成员和保护(protected)成员n n作用:增加灵活性,使程序员可以在封装和快速性方面做合理选择第95页/共109页友元函数友元函数n n把普通函数说明为友元的格式为:friend 类型 函数名(形参表);n n把其它类的成员函数说明为友元的格式为:friend 类型 类名:函数名(形参表);友元函数的说明必须在类体中给出友元函数原型声明第96页/共109页例:用友元函数计算两点间距离程序输出结果:(3,4)(6,8)distance=5第97页/共109页友元类 当一个类为另一个类的友元类时,该类的所有成员函数 均作为另一个类的友元函数则该类的所有成员都能访问另一个类的私有成员友元类的说明:将友元类名在另一个类中使用friend修饰说明friend class 友元类名;友元类Class a .Class b .friend class a;.第98页/共109页友元关系是单向的如果声明如果声明B类是类是A类的友元,类的友元,B类的成员函数就可以访问类的成员函数就可以访问A类的类的私有和保护数据,但私有和保护数据,但A类的成员函类的成员函数却不能访问数却不能访问B类的私有、保护数类的私有、保护数据。

    据第99页/共109页模板概述模板概述 n n在C+标准库中,几乎所有的代码都是模板代码n n模板将程序所处理的对象的类型参数化,使一段程序代码可以用于处理多种不同类型的对象n n采用模板编程,可以为各种逻辑功能相同而数据类型不同的程序提供一种代码共享的机制第100页/共109页模板的分类 模板分为:模板分为:函数模板函数模板 类模板类模板 第101页/共109页模板的实例化 模模板板通通过过参参数数实实例例化化可可以以构构建建具具体体的函数或类,的函数或类,称为模板函数和模板类称为模板函数和模板类第102页/共109页模板实例化示意图模板函数模板类模板模板类模板函数对象实例化实例化实例化第103页/共109页类模板类模板 是一种抽象通用的类,用它可生成一批具体的类类模板为类定义了一种模式,使类中的某些数据成 员、某些成员函数的参数、局部变量、函数的返回 值能取任意类型类模板的说明形式 template class ;模板参数的两种形式:1)class 或 typename 标识符 2)标识符第104页/共109页程序输出结果:7393.645.78例:一个简单的类模板说明第105页/共109页名空间 1.名空间 名空间是由程序设计者命名的程序中的一个区域,用于解决名称冲突问题。

    在所有名空间外部,是全局名空间,main()函数必须在全局名空间第106页/共109页名空间 2.定义名空间:namespace 名空间名.例:定义名空间举例两个名空间都定义了变量i 和函数max(),但因为可用名空间名对它们进行限定,所以它们都是惟一的,不会冲突第107页/共109页名空间 4.名空间中标识符的使用3.标准名空间:C+标准头文件是在标准名空间(std)中定义的b)和c)只在其作用域范围内有效第108页/共109页。

    点击阅读更多内容
    卖家[上传人]:深蓝爸爸
    资质:实名认证