




已阅读5页,还剩412页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
面向对象的设计思想,面向对象的思想最初出现于挪威奥斯陆大学和挪威计算机中心共同研制的simula 67语言中,随着的smalltalk-76和80语言推出,面向对象的的程序设计方法得到了比较完善的实现。 此后,面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统,交互式界面,分布式系统,网络管理结构和人工智能等领域。,面向对象的发展,面向对象思想,数据抽象 一种设计方法 把一组数据及作用与其上的操作组成一个设计实体或单位。接口说明外部可见,其实现是隐蔽的,不可见的。 发展的三个阶段,面向对象思想,抽象数据类型 抽象数据类型是指“一个值集和作用在该值集上的操作集”。抽象数据类型的定义只决定于其逻辑特性,与其具体的计算机内部实现无关。一个抽象数据类型可以分解为语法、语义、表示和算法4个部分。,面向对象思想,抽象数据类型的实现 实现抽象数据类型需要借助于高级程序设计语言; 在面向过程的语言中,用户可以自己定义数据类型; 在面向对象的程序设计语言中,借助于对象描述抽象数据类型。(class),面向对象思想,问题求解 面向对象设计方法:实现问题空间和问题求解空间的近似和直接模拟。,现实问题空间,解空间,面向对象的特点,封装机制 基于消息的通信 继承机制 多态机制,理解面向对象的基本概念对于学习和掌握面向对象的开发方法是十分重要的。,面向对象的世界观,把客观世界从概念上看成是一个由相互配合而协作的对象所组成的系统 面向对象=对象+分类+继承+通信 一个实例椅子,一个面向对象的实例椅子,对象,对象(object) 对象是用来描述客观存在的事物,它是构成系统的基本单位,是对客观世界中事物的抽象描述。,对象 行为(功能、方法、服务) 属性(数据),属性,行为,接口,对象,对象,对象,面向对象的基本概念,对象是由私有数据(属性)及作用于其上的一组操作(行为)所构成的一个封闭整体 由于对象的数据是私有的,所以要想访问其数据的正确方法是向该对象发送消息,让对象自身选择其内部相应的操作以完成对该项数据的访问 对象的动作取决于外界给对象的刺激,这就是消息,消息告诉对象所要求它完成的功能。对象具有一定的智能功能,即“知道”如何选择相应的操作来处理对象所接收的消息 从设计人员的角度看,对象是一个完成特定功能的程序块 从用户的角度看,对象为他们提供了所希望的行为,面向对象的基本概念,对象(object) 对象标识 对象生命周期,面向对象的基本概念,类(class) 类又称对象类(object class),是一组具有相同属性和相同操作的对象的集合。 在一个类中,每个对象都是类的实例(instance) ,它们都可以使用类中提供的函数。 类具有属性,用数据结构来描述类的属性, 类具有操作,它是对象的行为的抽象,操作实现的过程称为方法(method) ,方法有方法名,方法体和参数。,由于对象是类的实例,在进行分析和设计时,通常把注意力集中在类上,而不是具体的对象上。,图1 对象类的描述,对象和类的描述 类和对象一般采用“名字”、“属性”和“运算”来描述。,对象,类,属于某类的具体对象就是该类的实例。 一个类的不同实例必定具有: 相同的操作(或行为)的集合 相同的信息结构或属性定义,但可以有不同的属性值 不同的对象标识,面向对象的基本概念,面向对象的基本概念,消息(message) 对象之间的联系是通过传递消息来实现的。 消息就是向对象发出的服务请求(互相联系、协同工作等)。 是对象之间进行通讯的一种数据结构。 消息统一了“数据流”和“控制流”。,面向对象的基本概念,消息 - 消息传送与函数调用的区别 (1)函数调用可以带或不带参数,但是消息至少带一个参数,它表明接收该消息的对象,消息中告诉对象做什么的部分称为消息操作; (2)消息操作名类似于函数名,其本质区别在于:函数名代表一段可执行的代码,但消息操作名具体功能的选定还取决于接收消息的对象本身 (3)函数调用是过程式的(如何做),消息传送是说明式的(做什么),具体如何做,由对象根据收到的消息自行确定。,继承 (inheritance) 继承是使用现存的定义作为基础,建立新定义的技术。是父类和子类之间共享数据结构和方法的机制,这是类之间的一种关系。 继承性分: 单重继承:一个子类只有一个父类。即子类只继承一个父类的数据结构和方法。 多重继承:一个子类可有多个父类。继承多个父类的数据结构和方法。,现存类定义 父类(基类),新类定义 子类(派生类),继 承,图 3 继承性,继承,单继承,checking,savings,superclass (parent),subclasses,inheritance relationship,ancestor,descendents,继承,多继承,use multiple inheritance only when needed and always with caution!,multiple inheritance,封装(encapsulation) 封装是一种信息隐蔽技术,就是把对象的属性和行为相结合构成一个独立的基本单位,用户只能见到对象封装界面上的信息,对象内部对用户是隐蔽的。封装的目的在于将对象的使用者和对象的设计者分开,使用者不必知道行为实现的细节,只需使用设计者提供的消息访问对象,面向对象的基本概念,封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。,面向对象的基本概念,pos color ,公有消息,私有消息,存储结构,方法,协议,一个对象,面向对象的基本概念,封装的定义为: (1)一个限定所有对象内部软件的一个清楚界面; (2)一个描述这个对象和其它对象之间相互作用的接口 (3)受保护的内部实现,这个实现给出了由软件对象提供的功能细节,实现细节不能在定义这个对象的类的外面访问,封装 vs 继承,矛盾吗?no! 封装性主要指的是对象的封装性,引入继承机制后,对象仍然是封装地很好的实体,其它对象与它通信只能发送消息。 相似性:共享代码! 继承:静态共享代码 封装:动态共享代码,面向对象的基本概念,多态(polymorphism) 即一个名字具有多种语义。 同一对象接收到不同消息采用不同的行为方式 不同对象收到相同消息时产生不同的动作 重载(overload) 动态绑定 类属,多态性和动态绑定 多态性(polymorphism)是指相同的操作或函数、过程作用于不同的对象上并获得不同的结果。 即相同的操作的消息发送给不同的对象时,每个对象将根据自己所属类中定义的操作去执行,产生不同的结果。 例如: “绘图”操作,作用在“椭圆” 和“矩形” 上,画出不同的图形。,动态绑定(dynamic binding)是在运行时根据对象接收的消息动态地确定要连接的服务代码。 使用虚函数可实现动态联编,不同联编可以选择不同的实现,这便是多态性。 继承是动态联编的基础,虚函数是动态联编的关键。,多态性的实现举例,实现多态性的基本步骤(以c+为例): (1)在基类中,定义成员函数为虚函数(virtual); (2)定义基类的公有(public)派生类; (3)在基类的公有派生类中“重载”该虚函数; (4)定义指向基类的指针变量,它指向基类的公有派生类的对象。,注意:重载虚函数不是一般的重载函数,它要求函数名、返回类型、参数个数、参数类型和顺序完全相同。,例如:下面是实现“多态性” 的一个例子 #include using namespace std; class figure /定义基类 protected: double x,y; public: void set_dim(double i; double j=0) x=i; y=j; virtual void show_area() /定义虚函数 cout“no area computation define ”; cout“for this class.n”; ;,(1) 在基类中,将成员函数说明为虚函数(virtual);,class triangle: public figure / (2)定义基类的公有派生类 public: virtual void show_area() / (3)“重载”该虚函数 求三角形面积 ; class square: public figure / (2)定义基类的公有派生类 public: virtual void show_area() / (3)“重载”该虚函数 求矩形面积 ; class circle: public figure / (2)定义基类的公有派生类 public: virtual void show_area() / (3)“重载”该虚函数 求圆面积 ;,p= ,(4)运行过程中实现“动态绑定”,多态,figure,circle,triangle,square,area(),area(),area(),area(),类与对象,c+语言程序设计,本章主要内容,面向对象的思想 oop的基本特点 类概念和声明 对象 构造函数,析构函数 内联成员函数 拷贝构造函数 类的组合,回顾:面向过程的设计方法,重点: 如何实现细节过程,将数据与函数分开。 形式: 主模块+若干个子模块(main()+子函数)。 特点: 自顶向下,逐步求精功能分解。 缺点: 效率低,程序的可重用性差。,面向对象的思想,面向对象的方法,目的: 实现软件设计的产业化。 观点:解决问题属于自然界的。 自然界是由实体(对象)所组成。 程序设计方法: 使用面向对象的观点来描述模仿并处理现实问题。 要求: 高度概括、分类、和抽象。,面向对象的思想,(1)抽象,抽象是对具体对象(问题)进行概括,抽出这一类对象的公共性质并加以描述的过程。(如学生,教师, 课程) 先注意问题的本质及描述,其次是实现过程或细节。 数据抽象:描述某类对象的属性或状态(对象相互区别的物理量)。 行为抽象:描述某类对象的共有的行为特征或具有的功能。 抽象的实现:通过类的声明。,oop的基本特点,抽象实例钟表,数据抽象: int hour, int minute, int second 行为抽象: settime(), showtime(),oop的基本特点,抽象实例钟表类,class clock public: void settime(int newh, int newm, int news); void showtime(); private: int hour,minute,second; ;,oop的基本特点,抽象实例人,数据抽象: char *name,char *sex, int age, int id 行为抽象: 生物属性角度: getcloth(), eat(), 社会属性角度: work(), promote() , 注意:同一个问题可能有不同的抽象结果:根据解决问题的要求不同,产生的抽象成员可能不同,oop的基本特点,(2) 封装,将抽象出的数据成员、行为成员相结合,将它们视为一个整体,即类。 目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只需要通过外部接口,以特定的访问权限,来使用类的成员。 实现封装:类声明中的,oop的基本特点,封装,实例: class clock public: void settime(int newh,int newm, int news); void showtime(); private: int hour,minute,second; ;,特定的访问权限,oop的基本特点,(3)继承与派生,为了重用引出了继函的概念。 是c+中支持层次分类的一种机制,允许程序员在保持原有类特性的基础上,进行更具体的说明。 实现:声明派生类第11章 昆虫的分类树,oop的基本特点,多态性,多态:同一名称,不同的功能实现方式。 目的:达到行为标识统一,减少程序中标识符的个数。 实现:重载函数和虚函数第12章,oop的基本特点,c+中的类,类是具有相同属性和行为的一组对象的集合,它为属于该类的全部对象提供了统一的抽象描述,其内部包括属性和行为两个主要部分。 利用类可以实现数据的封装、隐藏、继承与派生。 利用类易于编写大型复杂程序,其模块化程度比c中采用函数更高。,类 和 对 象,类与函数,函数是将逻辑上相关的语句与数据封装,用于完成特定的功能。 而类则是逻辑上相关的函数与数据的封装,它是对所要处理的问题的描述。,类 和 对 象,类的声明形式,类是一种用户自定义类型,声明形式: class 类名称 public: 公有成员(外部接口) private: 私有成员 protected: 保护型成员 ,类 和 对 象,公有类型成员,在关键字public后面声明,它们是类与外部的接口,任何外部函数都可以访问公有类型数据和函数。,类 和 对 象,私有类型成员,在关键字private后面声明,只允许本类中的函数访问,而类外部的任何函数都不能访问。 如果紧跟在类名称的后面声明私有成员,则关键字private可以省略。,类 和 对 象,保护类型,与private类似,其差别表现在继承与派生时对派生类的影响不同,第七章讲。,类 和 对 象,类的成员,class clock public: void settime(int newh, int newm, int news); void showtime(); private: int hour, minute, second; ;,类 和 对 象,成员数据,成员函数,void clock : settime(int newh, int newm, int news) hour=newh; minute=newm; second=news; void clock : showtime() couthour“:“minute“:“second; ,19,成员数据,与一般的变量声明相同,但需要将它放在类的声明体中。 class complex private: double real; double imag; public: void init(double r,double i)real=r;imag=i; double realcomplex()return real; double imagcomplex()return imag; double abscomplex() double t; t=real*real+imag*imag; return sqrt(t); ,类 和 对 象,成员函数,在类中说明原形,可以在类外给出函数体实现,并在函数名前使用类名加以限定。也可以直接在类中给出函数体,形成内联成员函数。 允许声明重载函数和带默认形参值的函数,类 和 对 象,带缺省形参值的函数,void clock:settime(int newh=0,int newm=0,int news=0) hour=newh; minute=newm; second=news; ,内联成员函数,为了提高运行时的效率,对于较简单的函数可以声明为内联形式。 内联函数体中不要有复杂结构(如循环语句和switch语句)。 在类中声明内联成员函数的方式: 将函数体放在类的声明中-隐式 使用inline关键字-显式,类 和 对 象,内联成员函数举例(隐式),class point public: void init(int initx,int inity) x=initx; y=inity; int getx() return x; int gety() return y; private: int x,y; ;,类 和 对 象,内联成员函数举例(显式),class point public: void init(int initx,int inity); int getx(); int gety(); private: int x,y; ;,类 和 对 象,inline void point: init(int initx,int inity) x=initx; y=inity; inline int point:getx() return x; inline int point:gety() return y; ,25,对象,类的对象是该类的某一特定实体,即类类型的变量。 声明形式: 类名 对象名; 例: clock myclock;,类 和 对 象,类中成员的访问方式,类中成员互访 直接使用成员名 类外访问 使用“对象名.成员名”方式访问 public 属性的成员,类 和 对 象,例 类的应用举例,#include using namespace std; class clock public: void settime(int newh,int newm,int news); void showtime(); private: int hour,minute,second; ; void clock:settime(int newh,int newm,int news) hour=newh; minute=newm; second=news; ,void clock:showtime() couthour“:”minute“:”second; void main(void) clock myclock; myclock.settime(8,30,30); myclock.showtime(); ,例 类的应用举例,结构与类,struct savings unsigned accountnumber; float balance; ; void fn() savings a; savings b; a.accountnumber=1; b.accountnumber=2; ;,结构与类的区别: 类中成员的缺省存储属性为私有的 结构体中的缺省存储属性为共有的,构造函数,由于类的封装性,不能像普通变量一样初始化 struct savings unsigned accountnumber; float balance; ; savings a=1,2000.0; savings b(2,3000.0);,构造函数和析构函数,构造函数,构造函数的作用是在对象被创建时使用特定的值去构造对象,或者说将对象初始化为一个特定的状态。 在对象创建时由系统自动调用。 如果程序中未声明,则系统自动产生出一个默认形式的构造函数 允许为内联函数、重载函数、带默认形参值的函数,构造函数和析构函数,构造函数举例,class clock public: clock (int newh, int newm, int news);/构造函数 void settime(int newh, int newm, int news); void showtime(); private: int hour,minute,second; ;,构造函数和析构函数,构造函数的实现: clock:clock(int newh, int newm, int news) hour= newh; minute= newm; second= news; 建立对象时构造函数的作用: void main() clock c (0,0,0); /隐含调用构造函数,将初始值作为实参。 c.showtime(); ,31,重载构造函数:,/ex.h #include class demo int x,y; public: demo(int a,int b) x=a; y=b; cout“constructor demo(int ,int)be calledn”; demo() cout“constructor demo() be calledn”; void show() cout“x=”xt“y=”yendl; ;,#include “ex.h” void main() demo d1(3,5); /a d1.show(); demo d2; /b d2.show(); 该程序的输出为: constructor demo(int ,int) be called x=3 y=5 constructor demo( ) be called x=946 y=928 (随机值),拷贝构造函数,拷贝构造函数是一种特殊的构造函数,其形参为本类的对象引用。 作用:使用一个对象(参数指定的对象),去初始化一个正在被建立的同类型对象。 class 类名 public : 类名(形参);/构造函数 类名(类名 &对象名);/拷贝构造函数 . ; 类名: 类名(类名 &对象名)/拷贝构造函数的实现 函数体 ,构造函数和析构函数,例 拷贝构造函数举例,class point public: point(int xx=0,int yy=0); point( point ,构造函数和析构函数,point:point(int xx,int yy) x=xx; y=yy; point:point (point,34,拷贝构造函数被调用的时机,(1)当用类的一个对象去初始化该类的另一个对象时系统自动调用拷贝构造函数实现拷贝赋值。 void main(void) point a(1,2); point b(a); /拷贝构造函数被调用 coutb.getx()endl; ,构造函数和析构函数,(2)若函数的形参为类对象,调用函数时,实参赋值给形参,系统自动调用拷贝构造函数。例如: void fun1(point p) coutp.getx()endl; void main() point a(1,2); fun1(a); /调用拷贝构造函数 ,构造函数和析构函数,拷贝构造函数被调用的时机,(3)当函数的返回值是类对象时,系统自动调用拷贝构造函数。例如: point fun2() point a(1,2); return a; /调用拷贝构造函数 void main() point b; b=fun2(); ,构造函数和析构函数,拷贝构造函数被调用的时机,拷贝构造函数,如果程序员没有为类声明拷贝初始化构造函数,则编译器自己生成一个拷贝构造函数。 这个构造函数执行的功能是:用作为初始值的对象的每个数据成员的值,初始化将要建立的对象的对应数据成员。 point(point b.x=a.x 如果没有定义这个函数 b.y=a.y,构造函数和析构函数,析构函数,完成对象被删除前的一些清理工作。 在对象的生存期结束的时刻系统自动调用它,然后再释放此对象所属的空间。 如果程序中未声明析构函数,编译器将自动产生一个默认的析构函数。,构造函数和析构函数,构造函数和析构函数举例,#include using namespace std; class point public: point(int xx,int yy); point(); /.其它函数原形 private: int x,int y; ;,构造函数和析构函数,point:point(int xx,int yy) x=xx; y=yy; point:point() /.其它函数的实现略,41,#include class q int x,y; public: q(int a=0,int b=0) cout“调用了构造函数!”endl; x=a; y=b; void p(void) coutxtyn; q() cout“调用了析构函数!”n; void main(void) q q(50,100); q.p(); cout“退出主函数!n”; 输出:调用了构造函数! 50 100 退出主函数! 调用了析构函数!,类的应用举例,一圆型游泳池如图所示,现在需在其周围建一圆型过道,并在其四周围上栅栏。栅栏价格为35元/米,过道造价为20元/平方米。过道宽度为3米,游泳池半径由键盘输入。要求编程计算并输出过道和栅栏的造价。,#include using namespace std; const float pi = 3.14159; const float fenceprice = 35; const float concreteprice = 20; /声明类circle 及其数据和方法 class circle private: float radius; public: circle(float r); /构造函数 float circumference(); /圆周长 float area(); /圆面积 ;,43,/ 类的实现 / 构造函数初始化数据成员radius circle:circle(float r) radius=r / 计算圆的周长 float circle:circumference() return 2 * pi * radius; / 计算圆的面积 float circle:area() return pi * radius * radius; ,44,void main () float radius; float fencecost, concretecost; / 提示用户输入半径 coutradius; / 声明 circle 对象 circle pool(radius);/自动调用构造函数 circle poolrim(radius + 3);,45,/ 计算栅栏造价并输出 fencecost = poolrim.circumference() * fenceprice; cout “fencing cost is ¥“ fencecost endl; / 计算过道造价并输出 concretecost = (poolrim.area() - pool.area()*concreteprice; cout “concrete cost is ¥“ concretecost endl; 运行结果 enter the radius of the pool: 10 fencing cost is ¥2858.85 concrete cost is ¥4335.39,46,例:复数 (类与对象、内联成员函数),#include #include class complex private: double real; double imag; public: void init(double r,double i) real=r;imag=i; double realcomplex() return real; double imagcomplex() return imag; double abscomplex() double t; t=real*real+imag*imag; return sqrt(t); ;,void main() complex a; a.init(1.1,2.2); cout“real of complex a=”a.realcomplex()endl; cout“image of complex a=”a.imagecomplex()endl; cout“abs of complex a=”a.abscomplex()endl; ,例:复数 (构造函数),#include #include class complex private: double real; double imag; public: complex(double r,double i) real=r;imag=i; double realcomplex() return real; double imagcomplex() return imag; double abscomplex() double t; t=real*real+imag*imag; return sqrt(t); ;,void main() complex a(1.1,2.2); cout“real of complex a=”a.realcomplex()endl; cout“image of complex a=”a.imagecomplex()endl; cout“abs of complex a=”a.abscomplex()endl; ,例:复数 (带缺省参数构造函数),#include #include class complex private: double real; double imag; public: complex(double r=0.0,double i=0.0) real=r;imag=i; double realcomplex() return real; double imagcomplex() return imag; double abscomplex() double t; t=real*real+imag*imag; return sqrt(t); ;,void main() complex a(1.1,2.2); complex b; complex c(1.0); cout“real of complex a=”a.realcomplex()endl; cout“image of complex a=”a.imagecomplex()endl; cout“abs of complex a=”a.abscomplex()endl; ,例:复数 (构造函数重载),#include #include class complex private: double real; double imag; public: complex(double r,double i) real=r;imag=i; complex() real=0.0; imag=0.0; double realcomplex() return real; double imagcomplex() return imag; double abscomplex() double t; t=real*real+imag*imag; return sqrt(t); ;,void main() complex a(1.1,2.2); cout“real of complex a=”a.realcomplex()endl; cout“image of complex a=”a.imagecomplex()endl; cout“abs of complex a=”a.abscomplex()endl; complex b; cout“real of complex a=”b.realcomplex()endl; cout“image of complex a=”b.imagecomplex()endl; cout“abs of complex a=”b.abscomplex()endl; 参数能不能给一个值 如:complex c(1.1);行吗?,例:复数 (析构函数),#include #include class complex private: double real; double imag; public: complex(double r=0.0,double i=0.0) real=r;imag=i; complex() cout“destructing.n”; double realcomplex() return real; double imagcomplex() return imag; double abscomplex() double t; t=real*real+imag*imag; return sqrt(t); ;,void main() complex a(1.1,2.2); cout“real of complex a=”a.realcomplex()endl; cout“image of complex a=”a.imagecomplex()endl; cout“abs of complex a=”a.abscomplex()endl; complex b; cout“real of complex a=”b.realcomplex()endl; cout“image of complex a=”b.imagecomplex()endl; cout“abs of complex a=”b.abscomplex()endl; ,例:复数 (拷贝构造函数应用a),#include #include class complex private: double real; double imag; public: complex(double r=0.0,double i=0.0) real=r;imag=i; complex(complex ,void main() complex a(1.1,2.2); cout“real of complex a=”a.realcomplex()endl; cout“image of complex a=”a.imagecomplex()endl; cout“abs of complex a=”a.abscomplex()endl; complex b(a); cout“real of complex a=”b.realcomplex()endl; cout“image of complex a=”b.imagecomplex()endl; cout“abs of complex a=”b.abscomplex()endl; ,例:复数 (拷贝构造函数应用b),#include #include class complex private: double real; double imag; public: complex(double r=0.0,double i=0.0) real=r;imag=i; complex(complex ,void display(complex p) cout“real of complex p=”p.realcomplex()endl; cout“image of complex p=”p.imagecomplex()endl; cout“abs of complex p=”p.abscomplex()endl; void main() complex a(1.1,2.2); display(a); ,例:复数 (拷贝构造函数应用c),#include #include class complex private: double real; double imag; public: complex(double r=0.0,double i=0.0) real=r;imag=i; complex(complex ,complex fun() complex a(1.1,2.2); return a; void main() complex a(1.1,2.2); p=fun(); cout“real of complex p=”p.realcomplex()endl; cout“image of complex p=”p.imagecomplex()endl; cout“abs of complex p=”p.abscomplex()endl; ,静态成员,全局对象不好,但复杂程序都是由许多程序员共同设计的,因此需要这种性的对象。 使用类中的静态数据成员-解决访问权限控制问题。 class employee prvate: int empno; int id; char *name; 需要一个成员来统计雇员的总数,这个成员放在哪?,静态成员,一个类的所有对象具有相同的属性。 属性值不同。 类属性:描述类的所有对象的共同特征的一个数据项,对于任何对象实例。它的属性值是相同的。,静态成员,静态成员,静态成员,静态数据成员 用关键字static声明 该类的所有对象维护该成员的同一个拷贝 必须在类外定义和初始化,用(:)来指明所属的类。,静态成员,例 具有静态数据成员的 point类,#include using namespace std; class point public: point(int xx=0, int yy=0) x=xx; y=yy; countp+; point(point ,静态成员,point:point(point ,28,在类的声明中仅仅对静态数据成员进行引用说明,必须在文件作用域的某个地方使用类名限定进行定义性说明,这时也可初始化。,注意(1)用类名初始化 (2)访问控制属性,静态函数成员,使用静态成员函数-解决操作合法性控制问题。 例:coutp的初始值如何输出? 静态成员函数 类外代码可以使用类名和作用域操作符来调用静态成员函数。 静态成员函数只能引用属于该类的静态数据成员或静态成员函数。,静态成员,静态成员函数举例,#include using namespace std; class application public: static void f(); static void g(); private: static int global; ; int application:global =0;,void application:f() global=5; void application:g() coutglobalendl; int main() application:f(); application:g(); return 0; ,静态成员,总结:,静态数据成员application:global 该类的所有对象维护该成员的同一个拷贝 必须在类外定义和初始化,用(:)来指明所属的类。 静态成员函数f() g() 类外代码可以使用类名和作用域操作符或者对象名来调用静态成员函数。,静态成员函数举例,class a public: static void f(a a); private: int x; ; void a:f(a a) coutx; /对x的引用是错误的 couta.x; /正确 ,静态成员,说明:,静态成员属于类,非静态成员属于对象。 静态成员函数只能引用属于该类的静态数据成员或静态成员函数。 由于静态成员不是对象成员,所以在静态成员函数f()的实现中不能直接引用类中声明的非静态成员。 在f()的实现中,可以通过对象a来访问x-a.x,静态成员,具有静态数据、函数成员的 point类,#include using namespace std; class point /point类声明 public: /外部接口 point(int xx=0, int yy=0) x=xx;y=yy;countp+; point(point ,静态成员,point:point(point /输出对象号,类名引用 ,32,例:#include class student public: student(int studentno=0) cout“creat one student”; noofstudents+; cout“noofstudents” noofstudents; studentno =9022100+noofstudents; cout“studentno”studentnoendl; student() cout“destruct ont student n”; noofstudents-;,staic int number() return noofstudents; protected: static int noofstudents; int stuedntno; ; int student:noofstudents=0; void fn() student s1; student s2; coutstudent:number()endl; void main() fn(); coutstudent:number()endl;,组合的概念,类中的成员数据是另一个类的对象。 可以在已有的抽象的基础上实现更复杂的抽象。 通过对复杂对象进行分解、抽象,使我们能够将一个复杂对象理解为简单对象的组合。 分解得到复杂对象的部件对象,这些部件对象比它高层的复杂对象更容易理解和实现。然后由这些部件对象来“装配”复杂对象。,类 的 组 合,举例,class point private: float x,y; /点的坐标 public: point(float h,float v); /构造函数 float getx(void); /取x坐标 float gety(void); /取y坐标 void draw(void); /在(x,y)处画点 ; /.函数的实现略,类 的 组 合,class line private: point p1,p2; /线段的两个端点 public: line(point a,point b); /构造函数 void draw(void); /画出线段 ; /.函数的实现略,49,类组合的构造函数设计,原则:不仅要负责对本类中的基本类型成员数据赋初值,也要对对象成员初始化。
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 我国5-6岁幼儿语言入学准备发展水平及其教育现状研究-以陕西省汉中市A幼儿园为例
- 2025至2030年单级单吸管道高温泵项目投资价值分析报告
- 2025年PVC塑胶地板项目可行性研究报告
- 安全生规章制度
- 糖尿病专科护理门诊介绍
- 青少年心理障碍的护理
- 肾病综合征疾病护理
- 无人驾驶汽车销售合同
- 销售工作计划
- 吉林省白城市第十四中学2025年高三第一次模拟考试物理试卷含解析
- 电炉炼钢工职业技能知识考试题(附答案)
- 依法治县业务培训
- 网络安全课件:防范钓鱼攻击与社工库检测分析
- 房屋市政工程生产安全重大事故隐患判定标准(2024版)宣传海报
- 2024年安全员A证考试题库及答案(1000题)
- 年度八一慰问部队物资采购 投标方案(技术方案)
- 院感相关知识应知应会
- 半导体品质培训
- 糖尿病的中医护理查房
- 《接触网施工》课件 6.3.1 接触网工程的竣工验收
- 《继电保护整定计算用新能源场站建模导则》
评论
0/150
提交评论