C++及Windows可视化程序设计第1章.ppt_第1页
C++及Windows可视化程序设计第1章.ppt_第2页
C++及Windows可视化程序设计第1章.ppt_第3页
C++及Windows可视化程序设计第1章.ppt_第4页
C++及Windows可视化程序设计第1章.ppt_第5页
已阅读5页,还剩219页未读 继续免费阅读

下载本文档

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

文档简介

C+及Windows可视化程序设计,总目录,第1章程序设计基础第2章结构化编程基础第3章构造类型初探第4章函数第5章对象和类第6章继承和派生类第7章多态性和虚函数,总目录,第8章类的成员和对象第9章运算符重载和流类库第10章面向对象课程设计第11章Windows程序基本风格第12章使用MFC类库编程第13章MFC文档/视结构第14章可视化设计实例,第1章这里是章的名称,1.1面向过程的程序设计方法1.2面向对象的程序设计方法1.3可视化程序设计1.4面向对象语言的发展1.5C+的面向过程和面向对象程序设计1.6C+的面向对象程序设计特点1.7数据对象和数据类型的属性,1.8C+的基本数据类型和表达式1.9面向对象的标记图1.10使用类和对象实例1.11程序的编辑、编译和运行的基本概念1.12本书的结构实验习题,计算机科学发展的每一步,几乎都在软件设计和程序设计语言中得到充分体现。软件是一个发展的概念,随着软件开发规模的扩大和开发方式的变化,人们开始将程序设计语言作为一门科学来对待。程序设计方法和技术在各个时期的发展,不仅直接导致了一大批风格各异的程序设计语言的诞生,而且对计算机理论、硬件、软件以及计算机应用技术等多方面都产生了深远的影响。本章将使用伪码,以设计一个输入三角形的3个顶点坐标、计算3条边的长度的算法为例,分别介绍基于过程、面向对象和可视化程序设计的基本概念,引入面向对象的概念并介绍C+程序和面向对象编程的基础知识。,本节将简要说明自然语言与程序设计语言之间的关系、程序设计语言发展过程、面向过程的编程思想及其不足之处。,1.1面向过程的程序设计方法,软件开发是对给定问题求解的过程。从认识论的角度看,可以归为两项主要活动:认识与描述。软件开发者将被开发的整个业务范围称作“问题域”(problemdomain),“认识”就是在所要处理的问题域范围内,通过人的思维,对该问题域客观存在的事物以及对所要解决的问题产生正确的认识和理解,包括弄清事物的属性、行为及其彼此之间的关系并找出解决问题的方法。因为人类的任何思维活动都是借助于他们所熟悉的某种自然语言进行的,所以开发人员对问题域的认识是人类的一种思维活动。,1.1.1自然语言与计算机语言之间的鸿沟,我们常常看到有人讲话很流利,但考虑问题时却很糊涂,这说明还需要具有正确的思维方法。尤其是在软件开发过程中,要求人们对问题域的理解,要比日常生活中对它的理解更深刻、更准确。这需要许多以软件专业知识为背景的思维方法。“描述”是指用一种语言把人们对问题域中事物的认识、对问题及其解决方法的认识描述出来。最终的描述必须使用一种能够被机器读得懂的语言,即编程语言。直接使用机器语言来编写程序是一种相当复杂的手工劳动,它要求使用者熟悉计算机的有关细节,一般的工程技术人员难以掌握。,汇编语言出现于20世纪50年代初期,其主要特征是可以用助记符来表示每一条机器指令。由于汇编语言比机器语言容易记忆,编程效率就比机器语言前进了一大步。但汇编语言程序的大部分语句还是和机器指令一一对应的,与机器的相关性仍然很强。用汇编语言编好的程序需要由相应的翻译程序翻译成机器语言程序后方可执行。用程序设计语言写成的程序称为源程序,可以在具有该种语言编译系统的不同计算机上使用。源程序必须翻译成机器语言才能执行。逐条翻译并执行的翻译程序称为解释程序,例如BASIC语言解释程序。而将源程序一次翻译成目标程序然后再执行的翻译程序称为编译程序,例如FORTRAN、C和C+编译程序。,高级语言起始于20世纪50年代末期,因为它们更接近自然语言和数学语言,所以用它们编写的程序可读性强,交流较方便。60年代中期,FORTRAN、COBOL、LISP和ALGOL语言已相继出现,70年代以来,随着结构化程序设计思想的日益深入,使得这段时期问世的几种程序设计语言的控制结构大为简化,比较有代表性的有Pascal和C语言等,它们均属于面向过程的程序设计语言。从60年代起,ALGOL、PL/1与COBOL都逐渐消失。尽管Pascal语言的许多结构用在Ada语言中,但它在70年代早期已度过了它的鼎盛时期,逐渐成为教学用语言。,目前仍在使用的较老的语言都经历了阶段性的修改,以便反映来自其他计算机领域的明显影响。例如,FORTRAN90和Ada95,LISP更新为ScherneLISP,以后又改为CommonLISP。这些语言又称为面向过程的语言。较新的语言如C+,则是从C语言演化而来的混合型面向对象语言。由此可见,人们借助自然语言所产生的对问题域的认识远远不能被机器理解和执行,而机器能够理解的编程语言又很不符合人的思维习惯。人们习惯使用的语言和计算机能够理解并执行的编程语言之间存在着很大的差距,称这种差距为“语言的鸿沟”。程序设计语言发展的趋势就是为了使这种鸿沟变窄。图1.1给出了随着语言发展鸿沟变窄的示意图。,图1.1语言的发展使鸿沟变窄,由于人的认识差距,所以问题域与自然语言之间也有缝隙。机器语言与自然语言的鸿沟最宽,随着编程语言由低级向高级的发展,它们与自然语言之间的鸿沟在逐渐变窄。,C语言是美国Bell实验室开发成功的。当时的高级语言基本上都不适合开发系统软件,而C语言却成功地开发了UNIX操作系统。它的表达式简洁,具有丰富的运算符和良好的控制结构与数据结构。目前,其应用领域已不限于系统软件的开发,而成为最流行的程序设计语言之一。C语言是典型的面向过程的语言。所谓“面向过程”,就是不必了解计算机的内部逻辑,而把精力主要集中在对如何求解问题的算法逻辑和过程的描述上,通过编写程序,把解决问题的步骤告诉计算机。,1.1.2面向过程与结构化程序设计,【例1.1】给出输入三角形的3个顶点坐标,计算3条边的长度的过程算法描述。从面向过程的角度看,问题的实质是取得3个顶点的坐标,然后计算每两点之间的距离。可以将求解过程简单地描述如下:输入:3个坐标,即6个数据。输出:3条边的长度。算法设计:接受3组数据,每组2个数据。(x1,y1)第1组数据(x2,y2)第2组数据(x3,y3)第3组数据,计算每两点之间的距离AB(x1,y1)与(x2,y2)之间的距离AC(x1,y1)与(x3,y3)之间的距离BC(x2,y2)与(x3,y3)之间的距离输出(AB,AC,BC)由此可见,这种算法的特点是按部就班地求解,而且条理清晰易懂。随着应用需求的扩大和变化,软件生产的方法和效率仍然远远跟不上社会发展的需要。软件工作者开始考虑如何提高软件质量和生产效率,即使用系统方法代替个人经验、智慧、技巧等,使建立软件系统的过程遵从一系列规范化阶段,包括需求分析、概要设计、详细设计、实现、组装测试、运行和维护等。这就将软件设计工作推进到软件工程时代。,结构化程序设计被称为软件发展中的第3个里程碑,其影响将比前两个里程碑(子程序、高级语言)更为深远。结构化程序设计的概念,最早是由Dijkstra提出的。他在1965年召开的IEIP会议上提出“GOTO语句可以从高级语言中取消”,“一个程序的质量与程序中所含的GOTO语句的数量成反比”。,Tom.DeMarcod在结构化分析与系统规格说明教材中提出基于模型的软件工程概念,认为对于复杂软件系统的创建,必须首先为它们建立系统的书面模型。另一个有影响的软件理论是NiklansWirth提出的“算法+数据结构=程序”。将软件划分成若干个可以单独命名并分别编写的部分,称其为模块。模块化使软件能够有效地管理、维护、分析和处理复杂问题。在20世纪80年代,软件工作者普遍接受了模块化程序设计方法,接下来就是争论如何建立模块。有人认为最佳途径是使用函数,有人认为每个模块只应容纳一个数据结构,有人认为每个模块只应做一件事,还有人提出了事件驱动概念。这些代表性解决方案也促进了程序设计语言的发展。,C语言是结构化程序设计语言,它的程序设计特点就是函数设计。所谓函数,就是模块的基本单位,是对处理问题的一种抽象。例如,将求绝对值的功能抽象为abs(参数),就有abs(5)=5和abs(-55)=55。称abs为求一个数的绝对值函数,而称5和-55为函数abs的参数。把一切逻辑功能完全独立的或相对独立的程序部分都设计成函数,并让每一个函数只完成一个功能。这样,一个函数就是一个程序模块,程序的各个部分除了必要的信息交流之外,互不影响。相互隔离的程序设计方法就是模块化程序设计方法。C语言的这种程序结构化和模块化设计方法,特别适合于大型程序的开发。它解决了过去组成大系统时所产生的多文件的组织与管理问题。,在程序规模比较大时,一般是根据结构化程序设计方法将程序划分成多个源文件。在编译该程序时,可以按一个个源文件为单位,分别进行编译并产生与之对应的目标文件,然后再用连接程序把所生成的多个目标文件连接成一个可执行文件。称C语言的这种编译过程为分块编译。C语言的这种分块编译处理方式可以使一个程序同时由多个人进行开发,为大型软件的集体开发提供了有力的支持。分块编译的优点还在于修改一个源文件中的程序后,并不需要把整个程序的所有文件重新编译,这就大大节省了时间。下面是用C+语言编写一个求三角形两点之间距离时面向过程的算法思想。,输入:3个坐标,即6个数据。输出:3条边的长度。算法设计:接受3组数据,每组2个数据。(x1,y1)第1组数据(x2,y2)第2组数据(x3,y3)第3组数据计算每两点之间的距离ABfunc(x1,y1,x2,y2)ACfunc(x1,y1,x3,y3)BCfunc(x2,y2,x3,y3),输出(AB,AC,BC)/函数func的说明func(a,b,c,d)参数:a,b,c,d功能:求(a-c)2+(b-d)2的平方根函数func相当于C+函数库中的sqrt函数,可以直接使用sqrt函数求平方根。例如:ABsqrt(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)由此可以看出,面向过程的程序设计的关键是考虑使用结构化设计方法,使程序模块化。因为它是以函数过程和数据结构为中心,所以不能直接反映出人类认识问题的过程。,由此可见,现代计算机是面向算法的自动机,算法通过程序告诉计算机如何执行,构成程序的符号系统是语言,它是描述算法的工具。计算机语言(程序设计语言)的发展过程就是其功能不断完善、描述问题的方法逐步接近人类思维方式的过程。在计算机语言的发展过程中,新技术和新思想也不断出现。因为C+是混合型语言,所以可以使用C+编译器所提供的对象,设计出更好的、面向过程的软件系统。,程序设计语言是计算机科学中一个不断变化的领域。有的语言开始退出舞台,让位给新的语言(如ML,Smalltalk,Prolog)。有的语言,如FORTRAN则不断地演化发展着,以巩固自己的地位。同时,人们又力求开发出更好的程序设计语言。,1.2面向对象的程序设计方法,结构化程序设计技术是20世纪70年代研究的中心问题,而今天的热点则是面向对象程序设计语言,如Smalltalk,Traits,Eiffel和Java等语言都是面向对象的程序设计语言。C+则是在标准C语言的基础上,引入“面向对象”概念而扩充形成的混合型面向对象语言。面向对象的程序设计方法不是以函数过程和数据结构为中心,而是以对象代表求解问题的中心环节。它追求的是现实问题空间与软件系统解空间的近似和直接模拟。这就改变了原来计算机程序的分析、设计和实现的过程与方法之间的脱节和跳跃状态,从而使人们对复杂系统的认识过程与系统的程序设计实现过程尽可能地一致。,面向对象方法的产生,是计算机科学发展的要求。20世纪80年代,特别是90年代以来,软件的规模进一步扩大,对软件可靠性和代码可重用性的要求也进一步提高。就是在这样的背景下,面向对象的程序设计方法应运而生。和传统的程序设计方法相比,面向对象的程序设计具有抽象、封装、继承和多态性等特征。其实,“面向对象”不仅仅作为一种技术,更作为一种方法论贯穿于软件设计的各个阶段。面向对象的技术在系统程序设计、数据库及多媒体开发等领域都得到广泛应用。专家们预测,面向对象的程序设计思想将会主导今后程序设计语言的发展。,【例1.2】给出输入三角形的3个顶点坐标,计算3条边的长度的面向对象的算法描述。根据“问题域”设计程序模块。这里首先从顶点坐标考虑,顶点坐标就是一个点,通过这个点,可以得到它与另一个点的距离,从而将平面抽象为点对象的集合。三角形的3个顶点就是点类的3个实际对象。求三角形的3条边的边长,就是求每两个点对象之间的距离。因此,重点应放在如何描述这个点类上。设计Point类,这个类的属性具有两个坐标值(x,y)。它表现的行为是能初始化这个点的属性值,对于不同的点的对象,具有不同的属性值(也就是不同的x和y值)。,这个点类能向外界提供自己的属性值,并能计算它与另一个对象之间的距离。由此推知,可以像图1.2那样描述这个类。,图1.2point类示意图,第1个方框中是类名,第2个方框中是坐标点的数据,称为属性(或称数据成员)。第3个方框中表示类所提供的具体操作方法,实际上是如何使用数据x和y,以实现预定功能的成员函数。为了简单,假设只有一个带有两个参数的Point函数(以后将会看到,类Point可以有多个功能各异的同名成员函数),如果需要定义对象A,使用的方法如下:PointA(x1,y1);这里x1和y1是对象A的坐标。,对于对象A和对象B之间的距离,既可以表示为A.Getlength(B),也可表示为B.Getlength(A)。这个道理很明显,只要表示为两个点的对象即可。至于是A发出求A与B之间的距离的消息,还是B发出求B与A之间的距离的消息,则是无关紧要的。它们是调用同一个消息处理函数GetLength。算法描述为:输入:3个类的对象。输出:任意两个对象之间的距离。算法设计:设计类Point,产生3个对象PointA(x1,y1)对象APointB(x2,y2)对象BPointC(x3,y3)对象C计算对象之间的距离ABA.Getlength(B)ACA.Getlength(C)BCB.Getlength(C)输出(AB,AC,BC),求解的中心环节是以点这个客观世界的对象为依据,这正符合人们对客观世界的认识。所描述的这个点的类很稳定,可以用它来描述其他对象。例如,从点出发,增加一个点组成一条线段,或增加一条半径来描述一个圆。经验证明,对任何软件系统而言,其中最稳定的成分是对应的问题域。与功能相比,一个问题域中的对象一般总能保持相对稳定性,因而,以面向对象方式构造的软件系统的主体结构也具有较好的稳定性和可重用性。因此,采用“消息+对象”的程序设计模式,具有满足软件工程发展需要的更多优势。如果有兴趣,还可以设计一个界面,在界面上完成输入并得到输出结果。例如,可以让程序输出如图1.3所示的界面,然后直接在输入框中输入数据。,图1.3使用界面输入的示意图,结构化程序设计的提出和发展主要是为了解决日益复杂和规模庞大的软件开发的要求。随着软件的进一步庞大和复杂,随着编程实践的深入,人们发现,当软件复杂到一定程度时,结构化程序设计也不足以满足需要。一般说来,当软件的规模在三四万行以内时,结构化的方法还是可以满足需要的,当程序的规模超过这个尺度时,开发和维护就会变得越来越困难。发生这种情况的根本原因是结构化程序设计方法与客观世界以及人们的分析思考方式都非常不一致。这种不一致实际上是不合理的一种表现。,这种不合理性的一个具体结果是,结构化程序设计中的分而治之的想法尽管非常好,但在结构化程序设计语言和结构化程序设计方法下却难以贯彻到底。比如,结构化程序设计要求尽量不用全局变量,但当程序规模大到一定程度时,以功能抽象为基础的结构化程序几乎不可避免地引入大量的全局变量。也就是说,实际上已经没有办法满足结构化程序设计的基本要求。在面向对象程序设计中,可以将一组密切相关的函数统一封装在一个对象中,从而可以合理又有效地避免全局变量的使用。可以认为,面向对象方法更彻底地实现了结构化程序设计的思想。结构化程序设计使用的是功能抽象,面向对象程序设计不仅能进行功能抽象,而且能进行数据抽象。“对象”实际上是功能抽象和数据抽象的统一。,面向对象的早期,软件界将精力集中于用面向对象解决代码编写(即OOP阶段)问题。因此,这方面是成熟得最早的,也是一开始就很有说服力的。面向对象程序大大提高了软件的重用性,其代码更容易理解,更容易维护,也更优美。当OOP取得了很大成功以后,软件界信心大增,人们把眼光投向了更广阔的领域,面向对象几乎被当成了软件界的万能良药。在这样的背景下,面向对象分析(OOA)和面向对象设计(OOD)成了人们研究的重点,一直到20世纪90年代中期,这方面的方法和技术才真正统一。1992年OMG(面向对象管理组)制定的面向对象分析和设计的国际标准UML(unifiedmodelinglanguage)问世。面向对象技术应用又达到了一个新的水平。,时至今日,各种面向对象的技术和方法仍在发展中。需强调的是,面向对象语言和面向对象编程不能简单地等同起来。正像不能说采用结构化程序设计语言编写的程序一定符合结构化编程的特点一样,并不能说采用面向对象语言的编程就一定具有充分的面向对象特性。从本节的例子可见,在面向对象程序设计技术中,对象是具有属性(又称状态)和操作(又称方法、行为方式和消息等)的实体。,所谓“可视化”程序设计,也有人将其称为“组件”设计。它的实质就是面向对象程序设计方法,只是系统为程序员做了大量工作,节省设计时间并使许多设计过程可见而已。但相应也带来新的问题,即要求程序员要熟悉软件环境及其工作原理。在上一节中,图1.3的界面是通过编程来实现的。也就是说,在程序运行之后才可以看见各个输入框和提示信息的位置,如果不满意,就要重新计算。可视化编程时,系统已经设计了许多可供选择的组件,而且位置及大小均可以灵活调节,大大方便了程序员,减轻了他们的工作负担。,1.3可视化程序设计,【例1.3】给出使用VisualC+6.0进行可视化设计的界面示意图。假如设计如图1.4的界面。这个界面更复杂了,增加了根据给定的3个点坐标,模拟显示这个三角形图形的界面部分。其实,使用VisualC+6.0很容易设计这个界面,实现起来也很简单。这里使用VisualC+6.0提供的组件设计界面,例如使用标签显示提示信息,使用文本编辑框接受输入信息或用来输出信息及模拟显示图形等。图1.3和图1.4的界面不仅直观,而且功能增强。它们可以反复计算,直到不愿继续时为止。,图1.4可视化设计的界面示意图,从上面的例子可以看到,面向对象设计首先是从给定问题抽象出类,然后根据类创建描述问题的对象并处理对象发出的各种消息。因此,又把面向对象程序设计看做是“对象+消息”,这与面向过程的编程思想是不同的。学习面向对象程序设计的首要问题是改变观念,一定要首先放弃过去那种考虑问题的方式。正是由于这个原因,有许多软件工作者认为,没有学过面向过程的程序设计方法,反而容易建立面向对象的概念。很多面向过程的程序员老手,在进行面向对象程序设计时,反而容易走面向过程的老路。,面向对象程序语言发展的主要里程碑是Smalltalk语言,它完整地体现并进一步丰富了面向对象的概念。1980年美国XeroxPaloAlto研究中心推出了Smalltalk后,相继开发了配套工具环境,使之走向实用,其缺点是人们需要从头学习一门全新的语言。在20世纪80年代中期,面向对象语言已形成几大类别:一类是纯面向对象的语言,如Smalltalk和Eiffel;另一类是混合型的面向对象语言,如C+和ObjectiveC;还有一类是与人工智能语言结合形成的,如LOOPs、Flavors和CLOS;适合网络应用的有Java等。,1.4面向对象语言的发展,面向对象是一个认识论和方法学的基本原则。人对客观世界的认识和判断,常常采用由一般到特殊(演绎法)和由特殊到一般(归纳法)的两种方法,这实际上是对认识判断的问题域对象进行分解和归类的过程。面向对象分析(object-orientedanalysis,OOA)是面向对象软件工程方法的第一个环节,它包括一套概念原则、过程步骤和归类的过程。OOA的任务是采用面向对象方法,把对问题域和系统的认识理解,正确地抽象为规范的对象(包括类,继承层次)和消息连接关系,形成面向对象模型,为后续的面向对象设计(object-orienteddesign,OOD)和面向对象编程(object-orientedprogram,OOP)提供指导。而且OOA与OOD能够自然地过渡和结合,也是面向对象方法值得称道的一个优点。,OOA和OOD的区别主要是前者与系统的问题域更加有关,后者与系统的实现更加密切。一般来讲,只有在基本掌握了OOP的主要表达方法的基础上,才能从系统分析入手进行面向对象的软件设计。这也是目前研究的热门话题,即面向对象的软件工程方法。图1.5描述了这种方法从OOA到OOD,再到OOP和OOT(面向对象测试),都是紧密衔接的,填平了语言之间的鸿沟。图1.6描述了建立在面向过程基础上的传统的软件工程方法虽然在语言的鸿沟上铺设了一段平坦的路段,但这些路段并不连续,尤其是存在着需求分析和总体设计之间的鸿沟,造成致命的弱点。,图1.5面向对象的软件工程方法,图1.6传统的软件工程方法,如前所述,设计面向过程或者面向对象的程序,对语言本身并没有要求。也就是说,可以使用面向过程的语言设计面向对象的程序,典型的例子是使用C语言设计WindowsAPI程序。确实,最早的Windows程序就是使用面向过程的语言实现的。一般说来,如果使用面向对象的语言来设计面向对象的程序,将比使用面向过程的语言易于实现。所以程序员一般更喜欢使用C+语言编制Windows程序。,1.5C+的面向过程和面向对象程序设计,因为C+兼容了C语言,所以也可以使用C+编制面向过程的程序。虽然ANSIC新标准与老版本所定义的C语言相比,已经做了许多重要修改,使C语言更接近C+,例如引入了新的关键字void、const、volatile、signed和enum等。当仍然使用C语言编程时,虽然可以使用这些新特点,但却不能使用C+的其他特征,例如内联函数和引用等。显然,同样编制一个面向过程的应用程序,使用C语言就受到很多限制。如果使用C+语言,不仅可以使用C语言的所有特征,而且可以利用C+提供的对象,这样设计的面向过程的应用程序的质量肯定优于纯粹使用C语言设计的程序。,如果先集中精力学习使用C语言设计程序,结果是过多地研究如何将求解问题模块化,例如上面求三角形顶点之间距离的问题,将思想集中在编制函数,从数学上考虑计算两点之间的距离,忽略了三角形顶点与现实世界点对象的映射关系。另外,过多地强调面向过程,将给建立对象的概念造成不利因素。现在学生学习语言的过程与很多年以前大不相同。以前的学生甚至是从FORTRAN或Pascal语言开始学习,随着学习的需要,经过从C语言到C+语言的转换。,换言之,他们一般是因需要而下决心学习新的语言的。高年级的学生一般已经熟练地掌握了一门面向过程的语言,然后他们再去主动学习面向对象的编程方法。在学习中,他们会自发地将它们加以比较,融会贯通。现在的情况是,学生完全是被动地接受编程训练,如果仍然强化C语言的面向过程的训练,则很难马上让他们建立对象的概念。同样,虽然选用C+语言,但仍然先孤立地进行面向过程训练,然后再介绍面向对象,则所起的作用与选择C语言并没有什么不同。如果使用C+讲授面向过程知识的同时,及早引入对象的概念,把设计思想集中在对象上,则会起到事半功倍的效果。,通过使用C+提供的对象,建立过程设计的结构化概念并熟悉对象的使用方法,然后通过自己设计类来引入面向对象的抽象、封装、继承和多态性的概念。在设计面向对象程序的过程中,最终的程序实现还是离不开过程设计的,但这些过程的设计一般都很简单,并不需要很多技巧。正因为如此,介绍过程设计时就不需要像过去那样,将注意力集中在设计技巧上,面向对象的设计方法只给过程设计留下了简洁的设计风格。其实,这也正符合人们的认识论。人们在认识和研究客观世界时,是从事物(也就是对象)入手,然后再转向过程(事物是过程的集合体)。,应当指出的是,面向对象语言对程序设计的主要影响并不在于它的语法特征,而在于它所提供的自然问题求解的机制和结构。面向对象编程(OOP)将计算过程看做是分类过程加状态变换过程,即将系统逐步划分为相互联系的多个对象并建立这些对象的联系,以引发状态转换,实现系统计算任务。因此,要理解面向对象语言,应首先理解面向对象技术的基础原理和基本思想,然后再学习此类语言。实际上,如果我们能够深刻理解面向对象技术的原理和方法,即使不用面向对象的语言或系统,也能实现OOP。面向对象语言就是给用户提供一些支持面向对象程序设计的环境和管理工具,特别重要的是提供了对象概念和特征。,面向对象的程序设计方法要求语言必须具备抽象、封装、继承和多态性等关键要素。,1.6C+面向对象程序设计特点,称现实世界中客观存在的事物为对象,如前所述,整数是一个对象,平面上的点是一个对象,河流湖泊都是对象。复杂的对象可以由简单的对象组成,例如火车站对象又包含售票处、行李房、信号灯、站台、铁轨和通信设施等对象。这些对象各自又由许多对象组成,对象各自完成特定的功能。总之,世界万物皆对象。,1.6.1对象,售票处有各种规格的车票,这些车票表示售票处的静态特征。它提供发售车票的功能(操作),表示了售票处的动态特征。通过这种抽象归纳,C+可使用对象名、属性和操作三要素来描述对象。对象名用来标识一个具体对象。用数据来表示对象的属性,一个属性就是描述对象静态特征的一个数据项。操作是描述对象动态特征(行为)的一个函数序列(使用函数实现操作),也称为方法或服务。数据称为数据成员,函数称为成员函数。由此可见,C+中的对象是系统中用来描述客观事物的一个实体,是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的成员函数构成。对象结构如图1.7所示。,图1.7对象结构图,【例1.4】用简单对象表示平面上的A(1.5,5.4)和B(3.5,6.9)两个坐标点。对象名是“A”,A是一个点的对象。没有给对象A的属性赋值时,这只是个抽象名词。只有具有确定的属性值,才是一个具有确定位置的点。图1.8表示具体对象A和B的对象结构,用x坐标和y坐标表示坐标点对象的静态属性(称为位置属性)。假设x和y可以取实数值,C+中使用float标记它们是实数。假设暂且让点对象对外有显示属性值、设置属性值和移动位置等操作,这里分别使用成员函数display,setxy,move来实现这些操作。,图1.8具体对象A和B的结构图,抽象是一种从一般的观点看待事物的方法,即集中于事物的本质特征,而不是具体细节或具体实现。面向对象鼓励程序员以抽象的观点看待程序,即程序是由一组抽象的对象组成的。另外,又可以将一组对象的共同特征进一步抽象出来,从而形成“类”的概念。例如,从点A和B抽象出点的概念,这就是“点类”。这个类的本质是具有两个坐标属性和对这两个属性值进行操作的方法。A和B的区别只是属性值的不同,其方法是相同的。,1.6.2抽象和类,例如,当它们使用移动位置的函数之后,点的位置属性值将随之变化。它们都从当前位置移到一个新位置,代表了新坐标处的点对象。通过分析一组对象(A和B),抽取公共的行为将其放入到一个类中,取名为Point类,并用图1.9的Point类模型表示它。它也由类名、一组属性和一组操作等3部分组成。类的属性只是性质的说明,对象的属性才是具体的数据。所以,图1.9的Point类只是表示类名是Point,它的点位置是两个实数,但还没有具体的位置。只有像本节A和B两点那样,具有确定的属性值,才是Point类的具体对象,称它为类Point的一个实例。从图1.9可以推出图1.10所示的一般的“类”模型结构图。,图1.9Point类的结构图,图1.10类模型的结构图,抽象出这个类Point,就可以专心集中精力研究有关“点”的概念,如果再给它增加一个颜色属性,就可以知道这个类的所有对象都可以有颜色上的区别。无须再将注意力分散到有关任何一个具体点的坐标和颜色等细节中去。又如大家非常熟悉的整数类,通过研究发现,它的属性是一个整数集合,它提供的基本操作是四则运算。5和6是两个整数对象,5+6是使用整数类提供的相加求和操作。由此可见,类的概念来自于人们认识自然、认识社会的过程。在这一过程中,人们主要使用由特殊到一般的归纳法和由一般到特殊的演绎法。在归纳过程中,是从一个个具体的事物中把共同的特征抽取出来,形成一个一般的概念,这就是“归类”;在演绎的过程中,又把同类的事物,根据不同的特征分成不同的小类,这又是“分类”。,对于一个具体的类,它有许多具体的个体,这些个体叫做“对象”。举个例子,“人”是一个类,具有“直立行走、会使用工具”等一些区别于其他事物的共同特征;而张三、李四、王五等一个个具体的人,就是“人”这个类的一个个“对象”,同一类的不同对象具有相同的行为方式(如张三和李四都能直立行走、会使用工具),不同类的对象具有不同的行为(例如张三能使用工具,坐标点A则不能使用工具)。这种设计方法模仿了人们建立现实世界模型的方法,与人们认识客观事物的过程相一致,提高了编写程序的质量和可靠性。不过,对已掌握了过程设计思想的程序员来说,则必须改变原来的思维方法。,由此可见,一个对象是由一些属性和操作构成的。对象的属性和操作描述了对象的内部细节。类是具有相同的属性和操作的一组对象集合,它为属于该类的全部对象提供了统一的抽象描述,其内部包括属性和操作两个主要部分。这两个部分也是对象分类的依据,只有给出对象的属性和操作,才算对这个对象有了确切的认识和定义。类的作用是定义对象。类和对象的关系如同一个模具与用这个模具铸造出来的铸造件之间的关系。类给出了属于该类的全部对象的抽象定义,而对象则是符合这种定义的实体。所以,C+中将对象称做类的一个实例。,在程序中,每个对象需要有自己的存储空间以保存它们自己的属性值。所谓“一个类的所有对象具有相同的属性”,是指属性的个数、名称、数据类型相同,各个对象的属性值则可以互不相同,并且随着程序的执行而变化。至于操作,则是所有对象共同使用它们的类定义中给出的操作代码,在C+中,每个操作是一个“成员函数”,在Smalltalk中则称为“方法”。我们说同类对象具有相同的属性和操作,是指它们的定义形式相同,而不是说每个对象的属性值都相同。,举个简单的例子,电视机把各种部件都装在机箱里,遥控功能装在遥控器盒子中。用户通过遥控器操作电视机,既方便了用户,也保护了电视机。将类封装起来,也是为了保护类的安全,所谓安全,就是限制使用类的属性和操作。按照面向对象的封装原则,一个对象的属性和操作是紧密结合的,对象的属性只能由这个对象的操作来存取。,1.6.3封装,对象的操作分为内部操作和外部操作。内部操作只供对象内部的其他操作使用,不对外提供。外部操作对外提供一个消息接口,通过这个接口接收对象外部的消息并为之提供操作(服务)。对象内部数据结构的这种不可访问性称为信息(数据)隐藏。数据封装给数据提供了与外界联系的标准接口,无论是谁,只有通过这些接口,使用规范的方式,才能访问这些数据。由于程序员总是和接口打交道,因此就不必要了解数据的具体细节。简言之,封装就是把对象的属性和操作结合成一个独立的系统单位,并尽可能隐蔽对象的内部细节。,由此可见,封装要求一个对象应具备明确的功能,并具有接口以便和其他对象相互作用。同时,对象的内部实现(代码和数据)是受保护的,外界不能访问它们。封装使得一个对象可以像一个部件一样用在各种程序中,而不用担心对象的功能受到影响。数据封装一方面使得程序员在设计程序时可以专注于自己的对象,“各人自扫门前雪,莫管他人瓦上霜”,同时也切断了不同模块之间数据的非法使用,减少了出错的可能性。在类中,封装是通过存取权限实现的,如将每个类的属性和操作分为私有的和公有的两种类型。对象的外部只能访问对象的公有部分,不能直接访问对象的私有部分。,对象的另一个特点是继承。继承是一个对象可以获得另一个对象的特性的机制,它支持层次类这一概念,例如红香蕉苹果属于苹果类,而苹果类又属于水果类。通过继承,低层的类只需定义特定于它的特征,而共享高层的类中的特征。继承具有重要的实际意义,它简化了人们对事物的认识和描述。比如我们知道苹果可以吃,红香蕉继承苹果的特征,当然也可以吃。再如我们认识了轮船的特征之后,就知道客轮是轮船的特殊种类,它具有轮船的特征。当研究客轮时,只要把精力用于发现和描述客轮独有的那些特征即可。,1.6.4继承,不同的对象可以调用相同名称的函数,并可导致完全不同的行为的现象称为多态性。利用多态性,程序中只须进行一般形式的函数调用,函数的实现细节留给接受函数调用的对象。这大大提高了我们解决复杂问题的能力。举个最简单的例子,将两个数“相加”,这两个数可以是整数或实数,将“+”看做一个特殊函数,则3+5和5.2+8.6都是使用“+”来完成两个数相加的功能,这就是“+”体现的多态性。还可自己定义一个“+”功能(后面将会介绍如何实现这一称为运算符重载的方法),类的多态性将更加精彩,这将留待第7章讨论,本章不再赘述。,1.6.5多态性,各种语言之间的主要不同在于可用的数据类型、操作类型以及控制操作作用于数据序列的机制。语言的数据、操作和控制,将这些基本数据类型的概念推广到程序员定义的扩展,即所谓的数据抽象。通过软件模拟而得到一些典型类型,例如结构化的数据类型。本节从通用性角度,简单地考察在程序设计语言中数据对象和数据类型的属性。,1.7数据对象和数据类型的属性,一个数据对象就是能够存放和检索数据值的容器。数据对象有许多属性,最重要的属性是它的数据类型。这些属性决定数据对象可能存放的值的数目和类型,同时也决定了这些值的逻辑组织形式。数据值可以是单个数值、字符,也可以是指向另一个数据对象的指针。数据对象通常存放在计算机内存中,而数据值则表现为比特流(二进制位)模式。图1.11是其示意图。,1.7.1数据对象、变量和常量,图1.11数据对象和数据值,在程序中,对象存在是有时间性的,这个存在时间称为对象的生存期。在对象的生存期内,每个对象都可以用来保存数据值。如果一个数据对象包含的数据值总是为一个单位所操作,则称这个数据对象是基本的。例如对象5总是被整数单位所操作,整数对象就是基本对象。如果是其他数据对象的集合,则称之为数据结构。例如这个结构含有整数和实数两种基本数据对象,则可以用结构或类来实现,结构或类都称为数据结构。C+中称它们为构造类型数据对象。,程序员显式(程序设计中将直截了当的明显方式称为显式)定义和命名的数据对象称为变量。简单变量是有名字的基本数据对象。通常认为变量的值通过赋值操作修改,即数据对象和值之间的绑定在其生存期中可以改变。如果对象的名字与字母的大小写有关,称为大小写敏感,否则称为大小写不敏感。C+是大小写敏感的语言。常量是在生存期中被永久性地赋予一个值(或一些值)的有名字的数据对象。文字(文字常量)的名字恰好也表示了它的值(如以常量名21表示值为21的常量),即它们的名字和值是一个统一体。常量由编译器绑定。一般常用如下几个特性描述数据对象。,1.类型类型是将数据对象和它可以取得数据值的集合联系起来,例如正的整数对象(无符号整数对象)的可取值范围是所有自然数的集合。2.位置位置是数据对象所在内存的存储位置,通常由编译器分配,程序员不能修改。3.值这个绑定通常是赋值操作的结果,例如使用赋值操作符“=”,使一个整数对象的值为5。,4.名名由声明建立,是程序中可被引用的对象名,例如整数对象a,通过“inta;”建立。5.组件组件含有一个或多个数据对象,也可含有组件,它用指针绑定并通过指针改变其值。,数据类型是一个数据对象以及创建和操纵它们的操作集合所组成的类。每种语言都有构成该语言的基本数据类型,除此之外,也可以提供定义新数据类型的机制。一个数据类型规范的基本组件包括区别这个类型的数据对象的属性、这个类型的数据对象可能取的值以及定义这个类型的数据对象能提供的操作方法。1.属性任何数据对象的基本属性(如数据类型和名)在生存期内不变。注意:某个属性的值和数据对象所含的值是不同的。例如,当前整数对象a的值为5,整数对象的属性值不是5,而是整数集合。,1.7.2数据类型规范的基本组件,2.值数据对象的类型决定了它可取的可能值的集合。基本数据类型定义的值的集合是一个有最小值和最大值的有序集,并可以比较它们的大小。如整数类型包含的是整数集,这是一个有序集合。3.操作为一个数据类型定义的操作的集合,决定了如何操纵该类型的数据对象,体现了数据对象的动态特征。作为语言定义一部分的操作称为基本操作,例如整数的四则运算,就是整数对象的基本操作。对于面向对象的C+而言,程序员还可以自己定义操作。,对于基本数据类型,可以通过存储类型、实现、存储管理、多态性操作和类型检查等5部分实现。1.存储类型通常,数据对象的地址是指它们所占用的存储块的第1个字或字节的地址,数据对象的表示一般和它在内存中的位置无关。存储涉及到效率问题,例如C+的自动变量和静态变量的存储效率是不一样的。,1.7.3基本数据类型的实现,2.实现直接在声明时初始化。例如:autointa=5;声明一个自动存储型的整数对象a,其值为5的变量。C+默认存储类型是auto,可简记为:inta=5;也可先声明对象,然后再赋值。这也是常说的赋值和初始化问题。例如:inta;/声明a=5;/赋值,完成初始化符号“/”表示注释。3.存储管理还可以在程序中为对象动态分配存储区域。C+使用new运算符申请动态分配内存,但将它们具体分配在何处,则由编译器决定。,4.多态性操作最简单的例子是两个对象相加,例如A+B,不管A和B是整数相加,还是实数相加,操作符“+”都能自动识别。5.类型检查声明的重要目的是使得类型检查可以静态方式进行,而不需要动态地进行。动态要在程序运行时才能确定,静态在编译时即可确定。如果声明一个求绝对值的函数:intabs(int);/求整数的绝对值在程序中使用了“abs(8.89)”,8.89是实数,编译时就会报错。C+是强类型检查语言,正确声明有利于查错。,为了能通过小程序验证本节内容,先介绍一个简单而典型的C+程序。,1.8C+的基本数据类型和表达式1.8.1初识C+的函数和对象,【例1.5】演示乘法的示例程序。/*功能:将输入的数值乘以2*/#include/包含头文件usingnamespacestd;/使用命名空间intmain()/主程序intx(0),y(2);/初始化对象coutx=;/输出提示信息cinx;/接受输入数值coutx*y=/输出信息x*y/输出结果endl;/换行return0;/主函数main()的返回值,1.主函数用C+语言编写的程序称为C+语言源程序,简称C+程序并以.cpp作为文件扩展名。一个程序中必须有一个且只能有一个名为main的主函数。main并非是C+语言定义的关键字,但C+编译系统假设程序中定义有main函数。如果没有定义,程序将无法执行。因为C+保留了这个面向过程的主函数,所以称之为混合型语言。函数名称后面的两个圆括号里面放置的内容称为函数的参数列表,圆括号中是否有参数由编程者决定,main()的表达方式表示函数不接受任何参数,即为空的参数列表(无参数)。,main函数后面有一对花括号“”,可以把它看做程序体括号,还可以用它括起任何一组语句构成一个复合句(或称分程序),在一个程序或函数中至少应有一对花括号,而且符号“”和“”必须成对出现。2.使用注释程序中以“/”开始的内容是注释,有效范围至本行结束,注释的内容在编译时不产生目标代码。所谓目标代码,就是程序可以执行的代码。另外一种注释形式是沿用C语言的语法,即从“/*”开始,直到“*/”结束,它更适合注释占多行的情况。,3.使用输出和输入对象C+将数据从一个对象流向另一个对象的流动抽象为“流”。从流中获取数据的操作称为提取操作,向流中添加数据的操作称为插入操作。cin用来处理标准输入,即键盘输入。cout用来处理标准输出,即屏幕输出。它们都能对数据自动按照正确的默认格式处理。语句coutx=;是输出信息“x=”,用来提示用户输入一个数字。它就是C+的“语句”(statement),语句以分号作为结束。,就像自然语言中的句子一样,语句是C+程序的最小独立单元。因为cin和cout都不是C+语言本身定义的一部分,而是由C+的一套面向对象类体系(classeshierarchy)提供支持,并作为C+标准程序库(standardlibrary)的一员。要使用这个类体系,需先在主函数之前使用#include语句将其包含,以便让程序知道该类体系的定义。C+标准输入输出库的头文件是iostream,所以程序中使用下述语句:#include/包含头文件,符号“表示接受键盘输入,语句“cin;”将输入赋给对象x。符号“”和“”形象地表示了数据流动的方向。可以在一条语句中多次使用流的符号,也可以分为多个语句,例如可改写程序中的输出为如下形式:coutx*y=;/以分号结束coutx*y;/以分号结束coutendl;/与coutn;功能相同“coutendl;”与“coutxy;可以使用一行endl可以插在流的中间,下面语句将x和y分两行输出。coutxendlyendl;4.使用命名空间过去一直使用后缀“.h”标识头文件,在【例1.5】中没有使用后缀,其原因是新的C+标准引入了新的标准类库的头文件载入方式,即省略“.h”。不过,这时必须同时使用下述语句:usingnamespacestd;/使用命名空间,所谓命名空间(namespace)是一种将程序库名称封装起来的方法,它提高程序的性能和可靠性。目前无需深入了解它的含义,只要记住C+标准中的标准类库的变量与函数都属于命名空间std,若要在程序中使用cin和cout这两个iostream类的对象,不仅要包含iostream头文件,还得让命名空间std内的名称曝光,这条语句就是让命名空间中的名称曝光。C+新标准就是将标准类库的头文件与一般的头文件(需要使用后缀“.h”)区分开来,当然也可以自己定义符合标准库的头文件,使用这种头文件时,也需同时使用命名空间语句。有关命名空间的详细介绍见第10章。一般的程序都要具有如下两条语句:#include/包含头文件usingnamespacestd;/使用命名空间,5.对象的定义及初始化定义对象包括为它命名并赋予它数据类型。每个对象都隶属某个特定的数据类型。对象名称如果设计得好,能让人直接联想到该对象的属性。本程序使用两个整数对象x和y,一个设定为储存整数2,一个用来储存键入的值。int是C+的关键字,用来定义整数对象。可以在同一行有如下两条语句:intx=0;inty=2;/一行有多条语句,为了/可读性一般不这样做也可在一个语句中定义

温馨提示

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

评论

0/150

提交评论