已阅读5页,还剩412页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
面向对象的设计思想,面向对象的思想最初出现于挪威奥斯陆大学和挪威计算机中心共同研制的Simula67语言中,随着的Smalltalk-76和80语言推出,面向对象的的程序设计方法得到了比较完善的实现。此后,面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统,交互式界面,分布式系统,网络管理结构和人工智能等领域。,面向对象的发展,面向对象思想,数据抽象一种设计方法把一组数据及作用与其上的操作组成一个设计实体或单位。接口说明外部可见,其实现是隐蔽的,不可见的。发展的三个阶段,面向对象思想,抽象数据类型抽象数据类型是指“一个值集和作用在该值集上的操作集”。抽象数据类型的定义只决定于其逻辑特性,与其具体的计算机内部实现无关。一个抽象数据类型可以分解为语法、语义、表示和算法4个部分。,面向对象思想,抽象数据类型的实现实现抽象数据类型需要借助于高级程序设计语言;在面向过程的语言中,用户可以自己定义数据类型;在面向对象的程序设计语言中,借助于对象描述抽象数据类型。(Class),面向对象思想,问题求解面向对象设计方法:实现问题空间和问题求解空间的近似和直接模拟。,现实问题空间,解空间,面向对象的特点,封装机制基于消息的通信继承机制多态机制,理解面向对象的基本概念对于学习和掌握面向对象的开发方法是十分重要的。,面向对象的基本概念,面向对象的世界观,把客观世界从概念上看成是一个由相互配合而协作的对象所组成的系统面向对象=对象+分类+继承+通信一个实例椅子,一个面向对象的实例椅子,对象,对象(Object)对象是用来描述客观存在的事物,它是构成系统的基本单位,是对客观世界中事物的抽象描述。,对象行为(功能、方法、服务)属性(数据),属性,行为,接口,对象,对象,对象,面向对象的基本概念,对象是由私有数据(属性)及作用于其上的一组操作(行为)所构成的一个封闭整体由于对象的数据是私有的,所以要想访问其数据的正确方法是向该对象发送消息,让对象自身选择其内部相应的操作以完成对该项数据的访问对象的动作取决于外界给对象的刺激,这就是消息,消息告诉对象所要求它完成的功能。对象具有一定的智能功能,即“知道”如何选择相应的操作来处理对象所接收的消息从设计人员的角度看,对象是一个完成特定功能的程序块从用户的角度看,对象为他们提供了所希望的行为,面向对象的基本概念,对象(Object)对象标识对象生命周期,面向对象的基本概念,类(Class)类又称对象类(ObjectClass),是一组具有相同属性和相同操作的对象的集合。在一个类中,每个对象都是类的实例(instance),它们都可以使用类中提供的函数。类具有属性,用数据结构来描述类的属性,类具有操作,它是对象的行为的抽象,操作实现的过程称为方法(method),方法有方法名,方法体和参数。,由于对象是类的实例,在进行分析和设计时,通常把注意力集中在类上,而不是具体的对象上。,图1对象类的描述,对象和类的描述类和对象一般采用“名字”、“属性”和“运算”来描述。,对象,类,属于某类的具体对象就是该类的实例。一个类的不同实例必定具有:相同的操作(或行为)的集合相同的信息结构或属性定义,但可以有不同的属性值不同的对象标识,面向对象的基本概念,面向对象的基本概念,消息(Message)对象之间的联系是通过传递消息来实现的。消息就是向对象发出的服务请求(互相联系、协同工作等)。是对象之间进行通讯的一种数据结构。消息统一了“数据流”和“控制流”。,面向对象的基本概念,消息-消息传送与函数调用的区别(1)函数调用可以带或不带参数,但是消息至少带一个参数,它表明接收该消息的对象,消息中告诉对象做什么的部分称为消息操作;(2)消息操作名类似于函数名,其本质区别在于:函数名代表一段可执行的代码,但消息操作名具体功能的选定还取决于接收消息的对象本身(3)函数调用是过程式的(如何做),消息传送是说明式的(做什么),具体如何做,由对象根据收到的消息自行确定。,继承(Inheritance)继承是使用现存的定义作为基础,建立新定义的技术。是父类和子类之间共享数据结构和方法的机制,这是类之间的一种关系。继承性分:单重继承:一个子类只有一个父类。即子类只继承一个父类的数据结构和方法。多重继承:一个子类可有多个父类。继承多个父类的数据结构和方法。,现存类定义父类(基类),新类定义子类(派生类),继承,图3继承性,继承,单继承,Checking,Savings,Superclass(parent),Subclasses,InheritanceRelationship,Ancestor,Descendents,继承,多继承,Usemultipleinheritanceonlywhenneededandalwayswithcaution!,MultipleInheritance,封装(Encapsulation)封装是一种信息隐蔽技术,就是把对象的属性和行为相结合构成一个独立的基本单位,用户只能见到对象封装界面上的信息,对象内部对用户是隐蔽的。封装的目的在于将对象的使用者和对象的设计者分开,使用者不必知道行为实现的细节,只需使用设计者提供的消息访问对象,面向对象的基本概念,封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。,面向对象的基本概念,PosColor,公有消息,私有消息,存储结构,方法,协.议,一个对象,面向对象的基本概念,封装的定义为:(1)一个限定所有对象内部软件的一个清楚界面;(2)一个描述这个对象和其它对象之间相互作用的接口(3)受保护的内部实现,这个实现给出了由软件对象提供的功能细节,实现细节不能在定义这个对象的类的外面访问,封装vs继承,矛盾吗?No!封装性主要指的是对象的封装性,引入继承机制后,对象仍然是封装地很好的实体,其它对象与它通信只能发送消息。相似性:共享代码!继承:静态共享代码封装:动态共享代码,面向对象的基本概念,多态(Polymorphism)即一个名字具有多种语义。同一对象接收到不同消息采用不同的行为方式不同对象收到相同消息时产生不同的动作重载(overload)动态绑定类属,多态性和动态绑定多态性(Polymorphism)是指相同的操作或函数、过程作用于不同的对象上并获得不同的结果。即相同的操作的消息发送给不同的对象时,每个对象将根据自己所属类中定义的操作去执行,产生不同的结果。例如:“绘图”操作,作用在“椭圆”和“矩形”上,画出不同的图形。,动态绑定(dynamicbinding)是在运行时根据对象接收的消息动态地确定要连接的服务代码。使用虚函数可实现动态联编,不同联编可以选择不同的实现,这便是多态性。继承是动态联编的基础,虚函数是动态联编的关键。,多态性的实现举例,实现多态性的基本步骤(以C+为例):(1)在基类中,定义成员函数为虚函数(virtual);(2)定义基类的公有(public)派生类;(3)在基类的公有派生类中“重载”该虚函数;(4)定义指向基类的指针变量,它指向基类的公有派生类的对象。,注意:重载虚函数不是一般的重载函数,它要求函数名、返回类型、参数个数、参数类型和顺序完全相同。,例如:下面是实现“多态性”的一个例子#includeusingnamespacestd;classfigure/定义基类protected:doublex,y;public:voidset_dim(doublei;doublej=0)x=i;y=j;virtualvoidshow_area()/定义虚函数cout“Noareacomputationdefine”;cout“forthisclass.n”;,(1)在基类中,将成员函数说明为虚函数(virtual);,classtriangle:publicfigure/(2)定义基类的公有派生类public:virtualvoidshow_area()/(3)“重载”该虚函数求三角形面积;classsquare:publicfigure/(2)定义基类的公有派生类public:virtualvoidshow_area()/(3)“重载”该虚函数求矩形面积;classcircle:publicfigure/(2)定义基类的公有派生类public:virtualvoidshow_area()/(3)“重载”该虚函数求圆面积;,p=,(4)运行过程中实现“动态绑定”,多态,figure,Circle,Triangle,Square,area(),area(),area(),area(),类与对象,C+语言程序设计,本章主要内容,面向对象的思想OOP的基本特点类概念和声明对象构造函数,析构函数内联成员函数拷贝构造函数类的组合,回顾:面向过程的设计方法,重点:如何实现细节过程,将数据与函数分开。形式:主模块+若干个子模块(main()+子函数)。特点:自顶向下,逐步求精功能分解。缺点:效率低,程序的可重用性差。,面向对象的思想,面向对象的方法,目的:实现软件设计的产业化。观点:解决问题属于自然界的。自然界是由实体(对象)所组成。程序设计方法:使用面向对象的观点来描述模仿并处理现实问题。要求:高度概括、分类、和抽象。,面向对象的思想,(1)抽象,抽象是对具体对象(问题)进行概括,抽出这一类对象的公共性质并加以描述的过程。(如学生,教师,课程)先注意问题的本质及描述,其次是实现过程或细节。数据抽象:描述某类对象的属性或状态(对象相互区别的物理量)。行为抽象:描述某类对象的共有的行为特征或具有的功能。抽象的实现:通过类的声明。,OOP的基本特点,抽象实例钟表,数据抽象:intHour,intMinute,intSecond行为抽象:SetTime(),ShowTime(),OOP的基本特点,抽象实例钟表类,classClockpublic:voidSetTime(intNewH,intNewM,intNewS);voidShowTime();private:intHour,Minute,Second;,OOP的基本特点,抽象实例人,数据抽象:char*name,char*sex,intage,intid行为抽象:生物属性角度:GetCloth(),Eat(),社会属性角度:Work(),Promote(),注意:同一个问题可能有不同的抽象结果:根据解决问题的要求不同,产生的抽象成员可能不同,OOP的基本特点,(2)封装,将抽象出的数据成员、行为成员相结合,将它们视为一个整体,即类。目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只需要通过外部接口,以特定的访问权限,来使用类的成员。实现封装:类声明中的,OOP的基本特点,封装,实例:classClockpublic:voidSetTime(intNewH,intNewM,intNewS);voidShowTime();private:intHour,Minute,Second;,特定的访问权限,OOP的基本特点,(3)继承与派生,为了重用引出了继函的概念。是C+中支持层次分类的一种机制,允许程序员在保持原有类特性的基础上,进行更具体的说明。实现:声明派生类第11章昆虫的分类树,OOP的基本特点,多态性,多态:同一名称,不同的功能实现方式。目的:达到行为标识统一,减少程序中标识符的个数。实现:重载函数和虚函数第12章,OOP的基本特点,c+中的类,类是具有相同属性和行为的一组对象的集合,它为属于该类的全部对象提供了统一的抽象描述,其内部包括属性和行为两个主要部分。利用类可以实现数据的封装、隐藏、继承与派生。利用类易于编写大型复杂程序,其模块化程度比C中采用函数更高。,类和对象,类与函数,函数是将逻辑上相关的语句与数据封装,用于完成特定的功能。而类则是逻辑上相关的函数与数据的封装,它是对所要处理的问题的描述。,类和对象,类的声明形式,类是一种用户自定义类型,声明形式:class类名称public:公有成员(外部接口)private:私有成员protected:保护型成员,类和对象,公有类型成员,在关键字public后面声明,它们是类与外部的接口,任何外部函数都可以访问公有类型数据和函数。,类和对象,私有类型成员,在关键字private后面声明,只允许本类中的函数访问,而类外部的任何函数都不能访问。如果紧跟在类名称的后面声明私有成员,则关键字private可以省略。,类和对象,保护类型,与private类似,其差别表现在继承与派生时对派生类的影响不同,第七章讲。,类和对象,类的成员,classClockpublic:voidSetTime(intNewH,intNewM,intNewS);voidShowTime();private:intHour,Minute,Second;,类和对象,成员数据,成员函数,voidClock:SetTime(intNewH,intNewM,intNewS)Hour=NewH;Minute=NewM;Second=NewS;voidClock:ShowTime()coutHour:Minute:Second;,19,成员数据,与一般的变量声明相同,但需要将它放在类的声明体中。classcomplexprivate:doublereal;doubleimag;public:voidinit(doubler,doublei)real=r;imag=i;doublerealcomplex()returnreal;doubleimagcomplex()returnimag;doubleabscomplex()doublet;t=real*real+imag*imag;returnsqrt(t);,类和对象,成员函数,在类中说明原形,可以在类外给出函数体实现,并在函数名前使用类名加以限定。也可以直接在类中给出函数体,形成内联成员函数。允许声明重载函数和带默认形参值的函数,类和对象,带缺省形参值的函数,Voidclock:setTime(intNewH=0,intNewM=0,intNewS=0)Hour=NewH;Minute=NewM;Second=NewS;,内联成员函数,为了提高运行时的效率,对于较简单的函数可以声明为内联形式。内联函数体中不要有复杂结构(如循环语句和switch语句)。在类中声明内联成员函数的方式:将函数体放在类的声明中-隐式使用inline关键字-显式,类和对象,内联成员函数举例(隐式),classPointpublic:voidInit(intinitX,intinitY)X=initX;Y=initY;intGetX()returnX;intGetY()returnY;private:intX,Y;,类和对象,内联成员函数举例(显式),classPointpublic:voidInit(intinitX,intinitY);intGetX();intGetY();private:intX,Y;,类和对象,inlinevoidPoint:Init(intinitX,intinitY)X=initX;Y=initY;inlineintPoint:GetX()returnX;inlineintPoint:GetY()returnY;,25,对象,类的对象是该类的某一特定实体,即类类型的变量。声明形式:类名对象名;例:ClockmyClock;,类和对象,类中成员的访问方式,类中成员互访直接使用成员名类外访问使用“对象名.成员名”方式访问public属性的成员,类和对象,例类的应用举例,#includeusingnamespacestd;classClockpublic:voidSetTime(intNewH,intNewM,intNewS);voidShowTime();private:intHour,Minute,Second;voidClock:SetTime(intNewH,intNewM,intNewS)Hour=NewH;Minute=NewM;Second=NewS;,voidClock:ShowTime()coutHour“:”Minute“:”Second;voidmain(void)ClockmyClock;myClock.SetTime(8,30,30);myClock.ShowTime();,例类的应用举例,结构与类,StructSavingsunsignedaccountNumber;floatbalance;voidfn()Savingsa;Savingsb;a.accountNumber=1;b.accountNumber=2;,结构与类的区别:类中成员的缺省存储属性为私有的结构体中的缺省存储属性为共有的,构造函数,由于类的封装性,不能像普通变量一样初始化structSavingsunsignedaccountNumber;floatbalance;SavingsA=1,2000.0;SavingsB(2,3000.0);,构造函数和析构函数,构造函数,构造函数的作用是在对象被创建时使用特定的值去构造对象,或者说将对象初始化为一个特定的状态。在对象创建时由系统自动调用。如果程序中未声明,则系统自动产生出一个默认形式的构造函数允许为内联函数、重载函数、带默认形参值的函数,构造函数和析构函数,构造函数举例,classClockpublic:Clock(intNewH,intNewM,intNewS);/构造函数voidSetTime(intNewH,intNewM,intNewS);voidShowTime();private:intHour,Minute,Second;,构造函数和析构函数,构造函数的实现:Clock:Clock(intNewH,intNewM,intNewS)Hour=NewH;Minute=NewM;Second=NewS;建立对象时构造函数的作用:voidmain()Clockc(0,0,0);/隐含调用构造函数,将初始值作为实参。c.ShowTime();,31,重载构造函数:,/ex.h#includeclassDemointx,y;public:Demo(inta,intb)x=a;y=b;cout“Constructordemo(int,int)becalledn”;Demo()cout“Constructordemo()becalledn”;voidshow()cout“X=”xt“Y=”yendl;,#include“ex.h”voidmain()Demod1(3,5);/Ad1.Show();Demod2;/Bd2.Show();该程序的输出为:ConstructorDemo(int,int)becalledX=3Y=5ConstructorDemo()becalledX=946Y=928(随机值),拷贝构造函数,拷贝构造函数是一种特殊的构造函数,其形参为本类的对象引用。作用:使用一个对象(参数指定的对象),去初始化一个正在被建立的同类型对象。class类名public:类名(形参);/构造函数类名(类名Point(Point,构造函数和析构函数,Point:Point(intxx,intyy)X=xx;Y=yy;Point:Point(Point,34,拷贝构造函数被调用的时机,(1)当用类的一个对象去初始化该类的另一个对象时系统自动调用拷贝构造函数实现拷贝赋值。voidmain(void)PointA(1,2);PointB(A);/拷贝构造函数被调用coutB.GetX()endl;,构造函数和析构函数,(2)若函数的形参为类对象,调用函数时,实参赋值给形参,系统自动调用拷贝构造函数。例如:voidfun1(Pointp)coutp.GetX()endl;voidmain()PointA(1,2);fun1(A);/调用拷贝构造函数,构造函数和析构函数,拷贝构造函数被调用的时机,(3)当函数的返回值是类对象时,系统自动调用拷贝构造函数。例如:Pointfun2()PointA(1,2);returnA;/调用拷贝构造函数voidmain()PointB;B=fun2();,构造函数和析构函数,拷贝构造函数被调用的时机,拷贝构造函数,如果程序员没有为类声明拷贝初始化构造函数,则编译器自己生成一个拷贝构造函数。这个构造函数执行的功能是:用作为初始值的对象的每个数据成员的值,初始化将要建立的对象的对应数据成员。Point(PointB.X=A.X如果没有定义这个函数B.Y=A.Y,构造函数和析构函数,析构函数,完成对象被删除前的一些清理工作。在对象的生存期结束的时刻系统自动调用它,然后再释放此对象所属的空间。如果程序中未声明析构函数,编译器将自动产生一个默认的析构函数。,构造函数和析构函数,构造函数和析构函数举例,#includeusingnamespacestd;classPointpublic:Point(intxx,intyy);Point();/.其它函数原形private:intX,intY;,构造函数和析构函数,Point:Point(intxx,intyy)X=xx;Y=yy;Point:Point()/.其它函数的实现略,41,#includeclassQintx,y;public:Q(inta=0,intb=0)cout“调用了构造函数!”endl;x=a;y=b;voidP(void)coutxtyn;Q()cout“调用了析构函数!”n;voidmain(void)Qq(50,100);q.P();coutradius;/声明Circle对象CirclePool(radius);/自动调用构造函数CirclePoolRim(radius+3);,45,/计算栅栏造价并输出FenceCost=PoolRim.Circumference()*FencePrice;coutFencingCostis¥FenceCostendl;/计算过道造价并输出ConcreteCost=(PoolRim.Area()-Pool.Area()*ConcretePrice;coutConcreteCostis¥ConcreteCostendl;运行结果Entertheradiusofthepool:10FencingCostis¥2858.85ConcreteCostis¥4335.39,46,例:复数(类与对象、内联成员函数),#include#includeClasscomplexPrivate:doublereal;doubleimag;Public:voidinit(doubler,doublei)real=r;imag=I;doublerealcomplex()returnreal;doubleimagcomplex()returnimag;doubleabscomplex()doublet;t=real*real+imag*imag;returnsqrt(t);,voidmain()complexa;a.init(1.1,2.2);cout“realofcomplexa=”a.realcomplex()endl;cout“imageofcomplexa=”a.imagecomplex()endl;cout“absofcomplexa=”a.abscomplex()endl;,例:复数(构造函数),#include#includeClasscomplexPrivate:doublereal;doubleimag;Public:complex(doubler,doublei)real=r;imag=I;doublerealcomplex()returnreal;doubleimagcomplex()returnimag;doubleabscomplex()doublet;t=real*real+imag*imag;returnsqrt(t);,voidmain()complexa(1.1,2.2);cout“realofcomplexa=”a.realcomplex()endl;cout“imageofcomplexa=”a.imagecomplex()endl;cout“absofcomplexa=”a.abscomplex()endl;,例:复数(带缺省参数构造函数),#include#includeClasscomplexPrivate:doublereal;doubleimag;Public:complex(doubler=0.0,doublei=0.0)real=r;imag=I;doublerealcomplex()returnreal;doubleimagcomplex()returnimag;doubleabscomplex()doublet;t=real*real+imag*imag;returnsqrt(t);,voidmain()complexa(1.1,2.2);complexb;complexc(1.0);cout“realofcomplexa=”a.realcomplex()endl;cout“imageofcomplexa=”a.imagecomplex()endl;cout“absofcomplexa=”a.abscomplex()endl;,例:复数(构造函数重载),#include#includeClasscomplexPrivate:doublereal;doubleimag;Public:complex(doubler,doublei)real=r;imag=I;complex()real=0.0;imag=0.0;doublerealcomplex()returnreal;doubleimagcomplex()returnimag;doubleabscomplex()doublet;t=real*real+imag*imag;returnsqrt(t);,voidmain()complexa(1.1,2.2);cout“realofcomplexa=”a.realcomplex()endl;cout“imageofcomplexa=”a.imagecomplex()endl;cout“absofcomplexa=”a.abscomplex()endl;complexb;cout“realofcomplexa=”b.realcomplex()endl;cout“imageofcomplexa=”b.imagecomplex()endl;cout“absofcomplexa=”b.abscomplex()endl;参数能不能给一个值如:complexc(1.1);行吗?,例:复数(析构函数),#include#includeClasscomplexPrivate:doublereal;doubleimag;Public:complex(doubler=0.0,doublei=0.0)real=r;imag=I;complex()cout“destructing.n”;doublerealcomplex()returnreal;doubleimagcomplex()returnimag;doubleabscomplex()doublet;t=real*real+imag*imag;returnsqrt(t);,voidmain()complexa(1.1,2.2);cout“realofcomplexa=”a.realcomplex()endl;cout“imageofcomplexa=”a.imagecomplex()endl;cout“absofcomplexa=”a.abscomplex()endl;complexb;cout“realofcomplexa=”b.realcomplex()endl;cout“imageofcomplexa=”b.imagecomplex()endl;cout“absofcomplexa=”b.abscomplex()endl;,例:复数(拷贝构造函数应用A),#include#includeClasscomplexPrivate:doublereal;doubleimag;Public:complex(doubler=0.0,doublei=0.0)real=r;imag=I;complex(complex,voidmain()complexa(1.1,2.2);cout“realofcomplexa=”a.realcomplex()endl;cout“imageofcomplexa=”a.imagecomplex()endl;cout“absofcomplexa=”a.abscomplex()endl;complexb(a);cout“realofcomplexa=”b.realcomplex()endl;cout“imageofcomplexa=”b.imagecomplex()endl;cout“absofcomplexa=”b.abscomplex()endl;,例:复数(拷贝构造函数应用B),#include#includeClasscomplexPrivate:doublereal;doubleimag;Public:complex(doubler=0.0,doublei=0.0)real=r;imag=I;complex(complex,voiddisplay(complexp)cout“realofcomplexp=”p.realcomplex()endl;cout“imageofcomplexp=”p.imagecomplex()endl;cout“absofcomplexp=”p.abscomplex()endl;voidmain()complexa(1.1,2.2);display(a);,例:复数(拷贝构造函数应用C),#include#includeClasscomplexPrivate:doublereal;doubleimag;Public:complex(doubler=0.0,doublei=0.0)real=r;imag=I;complex(complex,complexfun()complexa(1.1,2.2);returna;voidmain()complexa(1.1,2.2);p=fun();cout“realofcomplexp=”p.realcomplex()endl;cout“imageofcomplexp=”p.imagecomplex()endl;cout“absofcomplexp=”p.abscomplex()endl;,静态成员,全局对象不好,但复杂程序都是由许多程序员共同设计的,因此需要这种性的对象。使用类中的静态数据成员-解决访问权限控制问题。classemployeeprvate:intEmpNo;intID;char*name;需要一个成员来统计雇员的总数,这个成员放在哪?,静态成员,一个类的所有对象具有相同的属性。属性值不同。类属性:描述类的所有对象的共同特征的一个数据项,对于任何对象实例。它的属性值是相同的。,静态成员,静态成员,静态成员,静态数据成员用关键字static声明该类的所有对象维护该成员的同一个拷贝必须在类外定义和初始化,用(:)来指明所属的类。,静态成员,例具有静态数据成员的Point类,#includeusingnamespacestd;classPointpublic:Point(intxx=0,intyy=0)X=xx;Y=yy;countP+;Point(Point,静态成员,Point:Point(Point,28,在类的声明中仅仅对静态数据成员进行引用说明,必须在文件作用域的某个地方使用类名限定进行定义性说明,这时也可初始化。,注意(1)用类名初始化(2)访问控制属性,静态函数成员,使用静态成员函数-解决操作合法性控制问题。例:coutP的初始值如何输出?静态成员函数类外代码可以使用类名和作用域操作符来调用静态成员函数。静态成员函数只能引用属于该类的静态数据成员或静态成员函数。,静态成员,静态成员函数举例,#includeusingnamespacestd;classApplicationpublic:staticvoidf();staticvoidg();private:staticintglobal;intApplication:global=0;,voidApplication:f()global=5;voidApplication:g()coutglobalendl;intmain()Application:f();Application:g();return0;,静态成员,总结:,静态数据成员Application:global该类的所有对象维护该成员的同一个拷贝必须在类外定义和初始化,用(:)来指明所属的类。静态成员函数f()g()类外代码可以使用类名和作用域操作符或者对象名来调用静态成员函数。,静态成员函数举例,classApublic:staticvoidf(Aa);private:intx;voidA:f(Aa)coutx;/对x的引用是错误的couta.x;/正确,静态成员,说明:,静态成员属于类,非静态成员属于对象。静态成员函数只能引用属于该类的静态数据成员或静态成员函数。由于静态成员不是对象成员,所以在静态成员函数f()的实现中不能直接引用类中声明的非静态成员。在f()的实现中,可以通过对象a来访问x-a.x,静态成员,具有静态数据、函数成员的Point类,#includeusingnamespacestd;classPoint/Point类声明public:/外部接口Point(intxx=0,intyy=0)X=xx;Y=yy;countP+;Point(Point,静态成员,Point:Point(Point/输出对象号,类名引用,32,例:#includeclassStudentpublic:Student(intStudentNo=0)cout“creatonestudent”;NoOfStudents+;cout“NoOfStudents”NoOfStudents;StudentNo=9022100+NoOfStudents;Cout“StudentNo”StudentNoendl;Student()cout“destructontstudentn”;NoOfStudents-;,staicintnumber()returnNoOfStudents;protected:staticintNoOfStudents;intStuedntNo;intStudent:NoOfStudents=0;voidfn()Students1;Students2;coutStudent:number()endl;voidmain()fn();coutStudent:number()ai;coutendl;for(i=0;i10;i+)coutai;coutendl;for(i=0;i10;i+)coutai;coutendl;for(p=a;p(a+10);p+)coutY=yy;,指针,指针变量作为函数实参,以地址方式传递数据,可以用来返回函数处理结果。例如:P9G。,指针与函数,例P9G,voidswap_vals(float*ptr1,float*ptr2)floattemp=*ptr1;*ptr1=*ptr2;*ptr2=temp;main()floatnum1,num2;cinnum1mum2;swap_vals(,动态申请内存操作符new,new类型名T(初值列表)功能:在程序执行期间,申请用于存放T类型对象的内存空间,并依初值列表赋以初值。结果值:成功:T类型的指针,指向新分配的内存。失败:0(NULL),动态存储分配,释放内存操作符delete,delete指针P功能:释放指针P所指向的内存。P必须是new操作的返回值。,动态存储分配,main()int*int_array;intno_els,i;coutno_els;/A_array=newintno_els;/Entertheelementsintothearray.for(i=0;iint_arrayi;/Displaythearrayvaluesjustentered.for(i=0;ino_els;i+)coutElementiis*(int_array+i)endl;deleteint_array;/Freetheallocatedmemory.,例动态创建对象举例,#includeusingnamespacestd;classPointpublic:Point()X=Y=0;coutDefaultConstructorcalled.n;Point(intxx,intyy)X=xx;Y=yy;coutConstructorcalled.n;Point()coutDestructorcalled.n;intGetX()returnX;intGetY()returnY;voidMove(intx,inty)X=x;Y=y;private:intX,Y;,动态存储分配,intmain()coutStepOne:endl;Point*Ptr1=newPoint;deletePtr1;coutStepTwo:endl;Ptr1=newPoint(1,2);deletePtr1;return0;,运行结果:StepOne:DefaultConstructorcalled.Destructorcalled.StepTwo:Constructorcalled.Destructorcalled.,157,例动态创建对象数组举例,#includeusingnamespacestd;classPoint/类的声明同上例,略;intmain()Point*Ptr=newPoint2;/创建对象数组Ptr0.Move(5,10);/通过指针访问数组元素的成员Ptr1.Move(15,20);/通过指针访问数组元素的成员coutDeleting.no_of_cols;/Allocaterequestedstorage:/(a)allocatestoragefortherows.data=newfloat*no_of_rows;/(b)allocatestorageforeachcolumn.for(j=0;jno_of_rows;j+)dataj=newfloatno_of_cols;,/Placesomevaluesinthearray.for(i=0;ino_of_rows;i+)for(j=0;jno_of_cols;j+)dataij=i*10+j;/Displayelementsofthearray.for(i=0;ino_of_rows;i+)for(j=0;jno_of_cols;j+)coutdataij;coutb;if(b0)intc;.具有块作用域的变量也称为局部变量。,作用域与可见性,类作用域,可以将类看成是一组有名成员的集合,除个别例外情况外,类作用域作用于特定的成员名,类及其对象有特殊的访问和作用域规则。例:类X的成员M,在X的任何一个没有重新声明变量M的函数成员中都可以访问到M,(1)即M在这样的函数起作用,(2)这样的M就具有类作用域。类的封装作用就在于限制数据的作用域。,作用域与可见性,类作用域,通过表达式x.M或者X:M访问。这是程序中访问对象成员的最基本的方法。X:M的方式用于访问类的静态成员。通过表达式prt-M,其中ptr为指向类的一个对象的指针。,作用域与可见性,命名空间作用域,一个大型的程序通常由不同模块构成,不同的模块甚至有可能是由不同人员开发的。不同模块中的类和函数之间有可能发生重名,这样就会引发错误。如南京路(上海的、武汉的),作用域与可见性,命名空间的语法形式:,namespace命名空间名命名空间内的各种声明(函数声明、类声明、)一个命名空间确定了一个命名空间作用域,凡是在该命名空间之内声明的、不属于前面所述各个作用域的标识符都属于该命名空间作用域。在命名空间内部可以直接引用当命名空间中声明的标识符,如果需要引用其他命名空间的标识符,需要使用下面的语法:命名空间名:标识符名,作用域与可见性,例:namespaceSomeNsclassSomeClass();SomeNs:SomeClassobj1;/声明一个SomeNs:SomeClass型的对象obj1,作用域与可见性,命名空间作
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 分公司合作共营协议模板
- 个人借款合同协议基本版
- 消防工程施工合同示范
- 2024年实验室技术服务合同范本
- 2024年版离婚协议书法律效力
- 第七单元《故都的秋》《荷塘月色》《我与地坛》联读公开课一等奖创新教学设计统编版高中语文必修上册
- 标准合资企业劳动合同
- 房屋租赁终止合同书撰写指南
- 建筑材料租赁合同模板
- 合同样本:无房产证购房合同
- 环境保护Theenvironmentalprotection英语演讲课件
- 等级医院现场评审迎检注意事项课件
- 含碘对比剂静脉外渗护理管理实践指南
- 2023年事故序列模型介绍
- 儿童免疫性疾病课件
- 牛津译林版五年级上册英语第五单元What do they do全部教案(共5课时)
- 中图版八年级地理上册《世界气候》复习课件
- 无损检测通用作业指导书
- 2023年中考语文复习:150个文言实词-课件(共183张PPT)
- ICU患者失禁性皮炎的预防及护理新进展
- 中秋节来历课件
评论
0/150
提交评论