测绘程序设计课件.ppt

上传人:小飞机 文档编号:1561113 上传时间:2022-12-05 格式:PPT 页数:277 大小:2.52MB
返回 下载 相关 举报
测绘程序设计课件.ppt_第1页
第1页 / 共277页
测绘程序设计课件.ppt_第2页
第2页 / 共277页
测绘程序设计课件.ppt_第3页
第3页 / 共277页
测绘程序设计课件.ppt_第4页
第4页 / 共277页
测绘程序设计课件.ppt_第5页
第5页 / 共277页
点击查看更多>>
资源描述

《测绘程序设计课件.ppt》由会员分享,可在线阅读,更多相关《测绘程序设计课件.ppt(277页珍藏版)》请在三一办公上搜索。

1、测绘程序设计与C+编程,长安大学 杨建华2012年8月,第一章 绪 论,第一节 本课程的研究内容,本课程主要内容测绘工程所涉及的数据计算、绘图、数据库管理、数据分析等,都可以使用计算机来完成。本课程主要讲述以下内容:(1) 面向对象软件设计的思想与C+语言。(2) 测绘数据处理常用工具类设计。矩阵的概念及其相关计算,角度-弧度互化的函数、测量正反算函数以及正态分位数函数。 (3) 基本平差程类adj设计。最小二乘平差与抗差估计。(4) 高程网平差类设计。水准网、三角高程网平差的相关计算问题。(5) 平面网平差类设计。三角网、边角网、测边网平差的相关计算问题。(6) GPS向量网平差类设计。观测

2、值为GPS基线向量网的三维坐标平差。(7) 测量坐标系转化类设计。测量坐标系转化程序设计技术,主要包括空间直角坐标系与大地地理坐标系的转换、高斯投影转换与平面直角坐标系的转换程序。(8) 综合应用类设计。建立一个综合应用类,封装以上七个数据处理功能,为用户的具体问题计算应用提供方便。,平差问题程序计算特点 平差程序计算:速度快、精度高、数据处理自动化;从程序设计的角度看,程序设计与平差计算相对独立。在程序设计时必须考虑需要处理的所有问题的普遍性和规律性。在程序计算时,选择平差方法的依据不同:在手工计算时,我们通常希望尽量降低计算工作量。当 必要观测数 t 多余观测数 r:条件平差; 必要观测数

3、 t 多余观测数 r:间接平差,这样,可以降低平差计算量。在计算机程序计算时,由于计算机计算的快速高效性,我们不是很关心计算量的问题,而把主要精力集中于方法实现的现实性方面,要求方法具有较强的规律性,便于程序设计的技术实现。在本课程中,我们使用间接平差方法进行程序设计。总之,我们在选择数学模型的时候,一定要考虑算法同计算机程序设计的特点相统一。,平差程序的基本要求平差程序设计与其它程序设计相同,应当满足一定的要求。(1)程序逻辑结构简单,清晰易读,符合结构化程序设计要求,便于扩展;(2)运算速度快,占用内存小,内外存之间的交换不宜过于频繁;(3)数学模型及计算方法正确、先进,计算结果精度高;(

4、4)适应性强,便于移植,充分考虑各种可能形式,尽量满足不同要求与需要;(5)方便用户,操作简便。数据输入与用户作业方式与习惯相统一,输出明了、齐全;尽量减少手工处理工作量,操作简便;人机交互性要强。上述要求,既体现在平差程序的总体设计中,也贯穿于平差程序设计的各个环节中。,C+平差程序的设计步骤面向对象分析 :提出概念模型面向对象设计 :确定概念模型确定概念模型中每个功能函数的具体算法 选定某种表达式来描述各种算法:伪代码代码编写:C+类设计与成员函数编写程序调试:类调试与系统软件调试编写用户使用说明:系统功能与结构;数据格式与处理过程,学习本课程的基本要求 (1) 理解并掌握C+语言面向对象

5、程序设计基本思想与基本技术,并应用于测绘程序设计中; (2) 理解并掌握测量平差基础、控制网平差基础等相关基础知识; (3) 勤动手、勤思考,阅读、编写相关功能程序,才能从根本上掌握面向对象的软件设计思想和测绘数据处理软件特点,理解并掌握面向对象的测绘程序设计技术。,第二节 模块化程序设计,模块执行某一特定任务的数据结构和程序代码。 模块=数据+函数模块化将待开发的软件系统分解成若干个小的、相对独立的小系统,以使每个小系统可以独立地开发、测试,最终组装成完整的软件。软件模块化的目的在于使软件的功能与结构清晰,降低软件开发难度、方便阅读理解、测试和修改。 (工业生产)独立的小系统称为模块。 程序

6、=数据+功能函数 按功能分块=结构化程序设计(C) 按组成结构分块=面向对象程序设计 (C+),结构化方法(C语言)功能分解:大事化小(将复杂的功能结构分解为一系列小的、相对独立、简单的局部功能结构)按功能划分模块,要求每个模块包含单一、具体的功能使每个模块独立性好,要求一个模块具有较强的内聚性和较弱的耦合性。方便于模块的独立开发、调试,同时,使模块具有很好的移植性。划分模块时,应当尽量减小模块间的耦合性,例如尽可能地使用局部变量就可以减小模块之间的耦合性。采用层次结构进行分析(方法):最上层模块是对系统整体功能的抽象;下层模块是对上层模块的逐步细化、分解、描述;重复(2),得出便于实现的独立

7、性好的模块,直到下层模块不可再分为止。在最下层,对“怎么做”作出精确的描述。,平差程序结构化分块方法,面向对象方法(C+语言) 结构化方法的缺陷: 1)基于功能分块的设计方法。 2)对数据与处理方法的分离与割裂。 3)可重用性差。 面向对象方法的基本思想: 面向对象方法直接分析现实世界或问题空间的概念组成结构,使用这些概念将需要研究的大问题划分成一系列独立的小问题。 在问题分析与软件设计时,与结构化设计方法的最大区别是结构化按照功能独立性要求进行功能模块划分;面向对象方法使用概念对数据与功能进行整体划分,其模块化程度更完整、独立性更好。,面向对象以客观世界固有的事物(对象)为基本单位来构造软件

8、系统,用人类一般的的思维方法来认识、理解和描述客观事物(软件系统),其思想本质是直接模拟现实问题空间的事物组成结构及其运行与功能关系。 对象=数据+算法(程序?) 程序=对象1+对象2+. 对象是一个包含数据与算法的相对独立的封闭系统,其内部结构特征为表示对象属性的数据和表示行为与功能的函数结构,对象内部的数据与功能是密不可分的。对象本身是一个独立的数据与功能单元,也就是说,一个对象就是一个(小)的软件系统。面向对象的思想是将客观事物看作具有属性和行为的对象;将问题分解为不同的对象,一个复杂对象由若干个简单对象构成。通过消息实现对象之间的联系,构造复杂系统;通过抽象找出同一类对象的共同属性和行

9、为,形成类;通过类的继承与多态实现代码重用。,第三节 面向对象程序设计,面向对象的基本概念类 分类把具有共同性质的事物划分为一类,得出一个抽象的概念。面向对象的类对具有相同属性和行为的一组对象集合的描述。 类之间的关系 一般与特殊:某个类的对象同时是另一个类的对象,如动物类与人类,鸟类与丹顶鹤类。 整体与局部:一个实体的物理构成,空间上的包容及组织机构等。 关联:两个类的对象实例之间具有某种依赖关系,如某人为某个公司工作,教师指导学生论文,某人拥有汽车。,封装 (对象)封装是把一组数据和与其有关的操作集合组装在一起,形成一个能动的实体。封装的目的是增强安全性和控制用户操作。用户不必了解对象内部

10、具体的实现细节,只需要通过外部接口来使用对象的成员。如:生活中的封装实体集成电路;面向对象中的封装实体对象。继承(类)保持已有类的特性而构造新类的过程称为继承。特殊类拥有其一般类的全部属性与服务,称作特殊类对一般类的继承。例如:如船与轮船;丹顶鹤与鸟类。当一个类拥有另一个类的所有数据和操作时,就称这两个类之间存在着继承关系。父类:被继承的已有类称为父类、基类。子类:继承了父类的所有数据和操作的类就为子类、派生类。单继承:一个类只有一个父类。多继承:一个类有多个父类。,派生(类)在已有类的基础上新增自己的特性而产生新类的过程称为派生。派生出的新类称为派生类。派生的目的:当新的问题出现,原有程序无

11、法解决(或不能完全解决)时,需要对原有程序进行改造(增加成员)。 消息(对象间)消息是对象之间建立联系的通信机制。提供服务的对象负责消息协议的格式和消息的接收,请求服务的对象提供输入信息,获取应答消息内容。消息的使用类似于函数调用。多态性:同样的消息被不同的对象接受所导致不同的行为 。多态意味着可以关联不同的实例对象,从而产生不同的行为,在面向对象的软件技术中,多态性也可以理解为不同的对象可以调用相同名称的函数,导致完全不同的行为的现象。 增加了面向对象软件系统的灵活性,进一步减少了信息冗余,提高了软件的可重用性和可扩充性 。,面向对象方法特点1)与人类习惯的思维方法一致面向对象的设计方法使用

12、现实世界的概念思考问题。它强调模拟现实世界中的概念而不强调算法。2)稳定性好现实世界中的实体是相对稳定的,因此以对象为中心构造的软件系统也是比较稳定的。 面向对象软件系统的结构是根据问题领域的模型建立起来的,而不是根据系统应完成的功能的分解建立的。因此当系统功能需求变化时,不会引起软件结构的整体变化。3)可重用性好软件重用定义:软件重用是指在不同的软件开发过程中重复使用相同或相似软件元素的过程。传统软件重用技术:利用标准函数库。但难以适应不同场合的不同需要,通常绝大多数函数都是新编的。4)易于开发大型软件产品软件成本降低,整体质量提高。,第四节 测绘数据处理程序设计,第五节 VC+6.0程序开

13、发环境Visual C+是微软使用C+语言的Windows程序程序开发平台,该平台支持C+控制台程序开发(dos以main()函数为程序主要入口)要求。C+兼容C,所以也可以用来设计C语言的结构化程序。本课程采用Visual C+6.0作为程序开发平台。Visual C+6.0是Windows程序,以菜单定义相关操作功能,应用方便。其桌面布局(图1):客户区是代码输入、编辑区,在该区域输入、编辑C/C+程序源代码;,图1 Visual C+6.0 开发环境,工作区是VC+程序开发管理区,在此系统列出软件相关的文件、Windows资源、相关函数、变量、类等结构。在控制台程序设计中,主要用来管理相

14、关结构、函数、定义的全局变量等。 输出区主要显示程序的编译、连接、调试等的结果或数据。在控制台程序开发中,主要用于编译结果显示,在此查看程序编译错误。*程序运行时,弹出Windows运行窗口(图2),默认条件下,背景为黑色,文字为白色。文字可浏览、不可编辑。在此可以以键盘输入程序数据。运行完毕,点击任意键关闭此窗口。以下在说明Visual C+6.0环境下,开发Dos程序的主要过程:,图 2 程序运行窗口,1选择“新建”,在弹出的“新建”窗口下点击“文件”,弹出窗口:,2. 代码输入、编辑与编译连接,3.程序运行,4.打开已有文件或工作区,如上图所示,点击文件菜单下“打开”选项,可以打开.Cp

15、p、.h等文件,也可以通过文件类型选择打开其他文件(例如.txt文件)。点击文件菜单下“打开 工作区”选项,可以打开.dsw文件,打开一个工作区文件,则已编译、连接的所有文件都会打开,包括已有的.exe文件。所以,可以直接运行该程序;也可以重新编辑源代码,再编译、运行。例:,第二章 C+语言新技术,2-1 函数重载,函数重载在C语言中,为定义不同类型数据相加的操作,必须使用不同的函数名来定义一组函数。Iplus() 整数相加;Dplus() 实数相加;Fplus() 浮点数相加;Cplus() 字符串相加。在C+语言中,可以使用更简洁的方法处理这种问题。对以上四种计算可以只使用一个函数名plu

16、s定义相关的不同函数。计算机函数编译的区别标志在于函数的参数不同。在应用时,就可以以一个相同的函数名调用一族函数。这就是C+语言函数重载的概念。使用一个已经存在的函数名定义一个新函数叫对原有函数的重载。,定义重载函数的关键在于同名函数应当具有不同的参数。参数不同:函数参数的类型不同或函数参数的个数不同。对于上例问题,可以定义一组重载函数(函数定义略):int plus(int a, int b);double plus(double a, double b);float plus(float a, float b);char* plus(char * a, char* b);在应用时,系统根据

17、参数的不同关联相关函数,如:int d=plus(2,14);coutplus(3.12, 5.899)endl;float s=plus(4.45 f, 5.66 f);重载的使用使程序的编写与使用具有方便性。应当注意的是,对于在操作和概念上不具有相似性的函数尽量不要使用重载,以免引起使用者的误解。,运算符重载 :C+运算符可以处理基本类型数据的计算问题,但不能用于用户定义的新类型(类)数据的计算。如果需要为用户定义的新类型定义运算符操作功能,可以使用运算符函数对已有运算符定义新功能。这种新功能定义叫运算符重载。运算符函数格式: 返回值 operator 操作符(参数表); 对类类型数据的运

18、算符重载可以使用友元函数与成员函数两种形式进行定义。在后面讲。,1、引用的概念 是C+区别于C的另一个技术特征。引用的作用在于函数的参数传递,使用引用,可以以变量名直接实现函数参数的双向传递。那什么是引用呢?简单地说,引用是对一个变量所取的别名,也就是给一个变量取的第二个名字。常量不可以建立引用。例如:int i;int 这里,i是一个变量,定义j为i的引用。系统不再为j分配存储空间,而让j与i使用相同的存储空间。这时,在程序中任何对j的访问就是对i的访问。引用的最主要作用在于函数参数的传递,也就是定义函数的参数为引用类型。,2-2 引 用,int Plus(int 该程序运行结果为6,11,

19、17在该程序中,我们发现,形参的改变导致了实参的改变。原因在于函数中定义的函数形参为实参的引用。这种作用在程序设计中具有很强的应用价值。,C语言使用标准输入/输出库函数完成数据的输入与输出,在使用中,需要判断数据类型,应用不方便。C+使用面向对象的方法实现数据的输入/输出,使用上更灵活、简便。C+使用输入输出流定义数据的键盘输入与屏幕输出,并预定义了两个应用对象cin和cout,cin用来实现数据的键盘输入;cout用来实现数据的屏幕输出,并为这两个对象分别定义了运算符和。在程序设计中,我们可以直接使用这两个对象及其运算符来完成相关操作。分析如下程序:,2-3 输入/输出流,#includev

20、oid main() int a,b,c;double d,e,f; char name20; coutab; coutde;coutname;c=a+b;f=d+e;cout“ name is ”nameendl;cout”c=”cendl;cout”f=”fendl;,程序中,endl是输出换行符(end-line)。运行程序: please input a,b 3 4 please input d,e4.3 3.4please input name杨建华运行结果:name is 杨建华c=7f=7.7由程序可以看出,使用输入输出流在程序设计中处理数据的输入与输出的方便性。,文件流文件流是

21、C+以面向对象的方法定义的文件格式的数据输入/输出方法。在需要处理大数据量时使用文件管理数据是非常必要的。从而也可以使数据处理的结果以文件形式被永久保存。C+有三种文件流:输入文件流 ifstream ,用来处理由文件的数据输入;输出文件流 ofstream ,用来处理向文件的数据输出;输入/输出文件流fstream,用来处理由文件的数据输入以及向文件的数据输出。具体应用过程如下:(以输入文件流为例),1、定义相关的流对象文件流类型的定义都在fstream.h头文件中,应用时需包含该文件。#include ifstream in; /定义输入文件流对象in,处理文件数据的 读入操作;ofstr

22、eam out; /定义输出文件流对象out,处理数据的文件输出操作;fstream io; /定义输入/输出文件流对象io,处理数据的文件读入/输出操作;2、以流对象打开相关文件io.open(“D:data.txt”); /对打开失败的异常处理略 3、数据读入写出ioabname; io123“ ”345“ ”“ ”endl;4、关闭文件文件使用结束,应当关闭相关文件in.close();,所谓动态,就是内存的使用由用户控制,在需要时分配,使用完毕随时释放;并且动态存储技术是在程序运行时分配和释放存储空间的。在C+中,使用两个操作符new和delete来完成相应的操作,其优越性表现在以下三

23、个方面:(1)new可以自动计算类型的大小并分配需要的内存空间,从而避免人为计算与分配可能造成的错误和浪费;(2)new 自动返回正确的指针类型,不必对返回类型进行类型转换;(3)可以使用new将待分配的内存单元初始化。在C+中,使用new动态分配存储空间;使用delete释放new分配的空间。(1)new的语法格式 类型指针=new 类型(类型初始化值);这里,类型可以是系统定义的基本数据类型,也可以是用户定义的结构体、枚举或C+的类类型。,2-4 动态存储,例如:int *s=new int; double *PI=new double(3.1415926);student *A=new

24、student100;程序运行时,动态分配一个整形存储空间,并把地址返回给指针s;动态分配一个double类型空间,初始化为3.1415926,并把地址返回给指针p;动态分配一个double类型数组空间,并把地址返回给指针A。这些动态分配的内存空间从分配后开始存在,直到delete释放它们,或者计算机关机为止(可见动态分配的存储空间具有“超静态”变量的性质)。所以,特别注意:new和delete应“配对”使用,以免造成计算机内存资源的浪费。(2)delete的语法格式 delete 类型指针;对于上面三个用new分配的动态存储单元,可用以下方法释放delete s; delete p; del

25、ete A;需要注意的是,释放数组空间时,不需要给出数组的大小。,第三章 面向对象程序设计与C+,3-1 面向对象程序设计思想,面向对象与结构化 结构化按功能分块;面向对象按对象分块; 结构化只分函数;面向对象数据与函数全分; 结构化方法复杂;面向对象方法简单; 面向对象是分块方法,结构化是实现细节。面向对象的基本概念 1、对象与封装 (成员变量、成员函数) 2、类与继承 3、消息 4、多态性,面向对象的软件分析与设计 面向对象分析的核心是分析并确定问题域中存在的概念及其关联关系。面向对象设计在根本是面向对象分析的继续,在明确了相关概念及其基本关系后,面向对象设计的根本目的是要确定软件系统的概

26、念结构及其具体关系。也就是确定每个类的具体功能、结构、关键技术、数学模型以及在类间存在的继承关系。 面向对象的C+语言 我们知道,C语言中的结构体可以用来表示一个概念的内涵,在结构体中加入函数就可以表示一个概念的所有属性与行为特征,从而表示一个完整的概念。所以,有人说,C+中的类就是在C语言结构体中加上函数,虽然这样的说法过于片面,但对于理解是很有帮助的。,3-2 C+类与对象,类是对具有相同属性和行为的一组对象的类型化声明/定义。它为属于该类的所有对象提供了统一的定义(抽象描述)方法。内部成分:成员变量(属性/状态)+成员函数(行为/功能)利用类可以实现数据的封装、隐藏、继承与派生。作用:定

27、义对象+建立新类(继承)利用类易于编写大型、复杂程序,其模块化程度远远高于C中采用的函数方法。C+类的概念是由C语言结构体发展来的。,类 和 对 象,类的声明格式,类是一种用户自定义类型,声明格式:class 类名 / class 为声明关键字 public: (外部接口) private: protected: ;/ 声明是语句,不要忘记“;”,类 和 对 象,公有类型成员,在关键字public后面声明,它们是类与外部的接口,任何外部函数都可以访问本类对象的公有类型成员变量和成员函数。作用:实现本类对象的对外服务(与用户需求有关)。,类 和 对 象,私有类型成员,在关键字private后面声

28、明的成员,只允许本类中的函数访问,而类外部的任何函数都不能访问。作用:用以实现该类的内部功能细节(这些细节与用户无关)。如果紧跟在类名称的后面声明私有成员,则关键字private可以省略。(类中不声明类型时缺省为private形式成员)结构体?,类 和 对 象,保护类型,对用户而言:与private相同,其差别表现在继承与派生时对派生类的影响不同,后面讲。,类 和 对 象,类的构造,class Clock public: void SetTime(int NewH, int NewM, int NewS); void ShowTime(); private: int Hour, Minute,

29、 Second;,类 和 对 象,成员变量,成员函数,类 名,类的成员函数通常在类的外部进行定义。格式:返回类型 类名:函数名(参数表) 注:1、注明类名 “:”表示属性(的) 2、返回类型与声明一致 3、定义时,必须给出形参名(在类中声明时可以只给出类型名),类 和 对 象,例:Clock类函数定义void Clock:SetTime(int NewH, int NewM,int NewS) Hour=NewH; Minute=NewM; Second=NewS; ShowTime();void Clock:ShowTime() coutHour:Minute:Secondendl;,50,

30、成员变量,与一般的变量声明形式相同,但需要将它放在类的声明体中。 !:不可在类中初始化(赋初值),?系统不为类的一般成员变量分配存储空间。?:(因为这里只是声明类型,int=5?)当对象被定义,对对象的成员变量赋初值。(系统为对象成员变量分配存储空间)int a=5;,类 和 对 象,成员函数,在类中说明原型,可以在类外给出函数体实现,并在函数名前使用类名加以限定。也可以直接在类中给出函数体,形成内联成员函数(内联函数)。作用:处理该类对象的数据。允许声明重载函数和带缺省形参值的函数。,类 和 对 象,对象,对象是该类的某一特定实体,即类类型的变量。声明形式: 1.类名 对象名; 2.定义类的

31、同时定义对象(全局对象)。例: Clock myClock; / float B;,类 和 对 象,类中成员的访问方式,类中成员互相访问直接使用成员名对象成员访问(类外访问)一般对象:使用“对象名.成员名”方式访问 public 类型的成员,. =“的”对象指针:使用“对象指针-成员名”方式访问 public 属性的成员 - =“的”类中的this指针任何类中都包含缺省的this指针this指向当前被操作对象使用this-a=8; 更容易理解,类 和 对 象,例7-1类的应用举例,#includeclass Clock ./类的声明略;/.类的实现略int main() Clock myClo

32、ck; myClock.SetTime(8,30,30); myClock.ShowTime();,类 和 对 象,类的构造函数,构造函数的作用是在创建对象时(定义对象时)使用特定的值构造对象,或者说将对象初始化为某一个特定的状态。在对象创建时由系统自动调用。是为系统编写的,通常不以对象方式访问。如果程序中未声明,则系统自动产生出一个默认形式的构造函数(不带参数)。允许为内联函数、重载函数、带默认形参值的函数不可以被继承(是一个类特有的成员)。格式:函数名与类名相同,无返回类型。,构造函数和析构函数,构造函数举例,class Clockpublic:Clock(int NewH=0,int N

33、ewM=0,int NewS=0); /声明构造函数void SetTime(int NewH,int NewM,int NewS);void ShowTime();private:int Hour,Minute,Second;,构造函数和析构函数,构造函数的实现:Clock:Clock(int NewH=0, int NewM=0, int NewS=0)Hour= NewH;Minute= NewM;Second= NewS;建立对象时构造函数的作用:int main() Clock a,c(10,20); /隐含调用构造函数,将初始值作为实参。 c.ShowTime();,58,拷贝构造

34、函数,拷贝构造函数是一种特殊的构造函数,其形参为本类的对象引用。其作用为使用已有对象对新对象初始化。class 类名 public : 类名(形参);/构造函数 类名(类名 &对象名);/拷贝构造函数声明 .;类名:类(类名 &对象名) /拷贝构造函数的定义 函数体 ,拷贝构造函数(例7-2),class Point public: Point(int xx=0,int yy=0)X=xx; Y=yy; Point(Point,构造函数和析构函数,Point:Point (Point / 类如果是工厂,对象就是产品。,61,拷贝构造函数(例7-2),当用类的一个已有对象去初始化该类的一个新对象

35、时系统自动调用拷贝构造函数实现拷贝赋值。int main() Point A(1,2); Point B(A); / 拷贝构造函数被调用 coutB.GetX()endl;,构造函数和析构函数,拷贝构造函数(例7-2),若函数的形参为类对象,调用函数时,实参赋值给形参,系统自动调用拷贝构造函数。例如:void fun1(Point p) coutp.GetX()endl; int main() Point A(1,2); fun1(A); /调用拷贝构造函数,构造函数和析构函数,拷贝构造函数(例7-2),当函数的返回值是类对象时,系统自动调用拷贝构造函数。例如:Point fun2() Poi

36、nt A(1,2); return A; /调用拷贝构造函数int main() Point B; B=fun2(); ,构造函数和析构函数,默认的拷贝构造函数,如果程序员没有为类声明拷贝构造函数,则编译器自己生成一个默认的拷贝构造函数。这个构造函数执行的功能是:用作为初始值的对象的每个数据成员的值,初始化将要建立的对象的对应数据成员(完全相同)。(若存在指针成员变量,引发问题?),构造函数和析构函数,析构函数,完成对象被删除前的一些清理工作。在对象的生存期结束的时刻系统自动调用它,释放此对象所属的空间。(料理后事)如果程序中未声明析构函数,编译器将自动产生一个默认的析构函数。只有一个(唯一性

37、)。不能被继承。(与构造函数相同)函数名与类名相同,为区别于构造函数,通常在函数名前加“”。无形参、无返回类型。(构造函数可以有形参),构造函数和析构函数,构造函数和析构函数举例,#includeusing 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; cout“Point classs constructor called”endl;Point:Poi

38、nt()cout“Point classs destructor called”endl;/.其他函数的实现略,68,类的应用举例(例7-3),一圆形游泳池如图所示,现在需在其周围建一圆形过道,并在其四周围上栅栏。栅栏价格为35元/米,过道造价为20元/平方米。过道宽度为3米,游泳池半径由键盘输入。要求编程计算并输出过道和栅栏的造价。,#include const float PI = 3.14159;const float FencePrice = 35;const float ConcretePrice = 20;/声明类Circle 及其数据和方法class Circle private

39、: float radius; public: Circle(float r); /构造函数 float Circumference(); /圆周长 float Area(); /圆面积;,70,/ 类的实现/ 构造函数初始化数据成员radiusCircle:Circle(float r)radius=r;/ 计算圆的周长float Circle:Circumference() return 2 * PI * radius; / 计算圆的面积 float Circle:Area() return PI * radius * radius;,71,void main () float radiu

40、s; float FenceCost, ConcreteCost; / 提示用户输入半径 coutradius; / 声明 Circle 对象 Circle Pool(radius); Circle PoolRim(radius + 3);,72,/计算栅栏造价并输出 FenceCost=PoolRim.Circumference()*FencePrice; coutFencing Cost is ¥FenceCostendl; /计算过道造价并输出 ConcreteCost=(PoolRim.Area()- Pool.Area()*ConcretePrice; coutConcrete Co

41、st is ¥ConcreteCostendl;运行结果Enter the radius of the pool: 10Fencing Cost is ¥2858.85Concrete Cost is ¥4335.39,73,静态成员,静态成员的概念: 一般情况下,同一个类不同对象的数据成员所占用的内存空间是不同的(描述不同对象具有不同的属性值)。在有些情况下,类的数据成员的值对每个对象都是相同的,如当前已创建对象的数量,这时可以将该数据成员声明为静态数据成员(对所有当前对象而言,占有相同的存储单元)。静态成员是属于类的,被所有对象共享。静态成员的生存期与类相同。静态成员的声明: 在声明成员时

42、以关键字static开头,例如: public: static int m_nCount;,静态成员分为静态数据成员和静态成员函数。静态数据成员类似于一般的static静态变量,它具有全局性。静态数据成员属于整个类,为类的所有对象共享(例:太阳、地球)。无论类的对象有多少,类的静态数据成员只有一份,存储在同一个内存空间。即使没有创建类的一个对象,类的静态数据成员也是存在的。使用静态数据成员保证了该数据成员值的唯一性。,静态成员的初始化:放在类定义的外部 int Person : m_nCount=0;,静态成员的访问:,公有静态成员:三种方式(1)通过对象访问,如: person1.m_nCo

43、unt=100;(2)利用类名和作用域限定符(:)访问,如:int Person:m_nCount=100; / 初始化(3)在成员函数中访问,如:m_nCount+;,私有和保护静态成员:只能在成员函数中访问,静态成员函数:,成员函数也可以是静态的,其声明方式与静态成员变量类似。如:public: static int GetCount();/ 获取静态数据成员静态成员函数也与一个类相关联,而不只与一个特定的对象相关联。区别非静态成员函数,静态成员函数没有this指针,因为类的静态成员函数只有一个运行实例。成员函数一般是公有的,可以通过对象、类名和作用域限定符、在成员函数中三种方式调用静态成

44、员函数。,静态成员函数只能访问类中的静态成员(成员变量和成员函数),而不能访问类的非静态成员。因为当通过类名和运算符“:”调用一个静态成员函数时,不能确定函数中所访问的非静态成员属于哪一个对象(思考:无对象情况)。 解决方法: 将对象作为静态成员函数的参数,然后在静态成员函数中通过对象访问它的非静态成员。,注 意,例,例 静态成员变量和静态成员函数的使用:,#include #include class Personprivate: char m_strName20; long m_ID; static int m_nCount; / 静态成员变量,表示已创建对象的数量public: Pers

45、on(char*, long);/ 构造函数 static int GetCount();/ 静态成员函数 static long GetID(Person);/ 对象作为静态成员函数的参数;,Person:Person(char* strName, long ID) strcpy(m_strName, strName); m_ID=ID; m_nCount+;/ 对象数目加1int Person:GetCount() return m_nCount;/ 访问静态成员变量long Person:GetID(Person x) return x.m_ID; / 不能直接访问非静态成员m_ID,i

46、nt Person:m_nCount=0;/ 初始化静态成员变量void main() Person e1(LiuJun,1101051); coutPerson:m_nCount , e1.m_nCount n; / 通过类或对象访问静态成员变量 coutPerson:GetCount() , ” Person:GetID(e1)n; / 通过类调用静态成员函数 coute1.GetCount() , e1.GetID(e1)n; / 通过对象调用静态成员函数 ,3.3 子对象与对象数组,A类中的成员变量是B类的对象。可以在已有抽象的基础上实现更复杂的抽象。A类构造函数应负责对象成员初始化。

47、,类 的 组 合,举例,class Point private: float x,y; /点的坐标 public: Point(float h,float v); /构造函数 float GetX(void); /取X坐标 float GetY(void); /取Y坐标;/.函数的实现略,类 的 组 合,class Line private: Point p1,p2; /线段的两个端点 public: Line(Point a,Point b); /构造函数 Void Draw(void); /画出线段;/.函数的实现略,84,含子对象类的构造函数,原则:不仅要负责对本类中的基本类型成员数据赋

48、初值,也要对对象成员初始化。声明格式:类名:类名(对象成员所需的形参,本类成员形参) :对象名1(参数),对象名2(参数),. 本类初始化 ,类 的 组 合,含子对象类构造函数的调用,构造函数调用顺序:先调用对象成员的构造函数(按内嵌时的声明顺序,先声明者先构造)。然后调用本类自身的构造函数。(析构函数的调用顺序相反)若为缺省构造函数(或者无形参),则对象成员的初始化也将调用相应的默认构造函数。,类 的 组 合,含子对象类的举例(二),class Part /部件类 public: Part(); Part(int i); Part(); void Print(); private: int

49、val;,类 的 组 合,class Whole public: Whole(); Whole(int i,int j,int k); Whole(); void Print(); private: Part one; Part two; int date;,88,Whole:Whole() date=0;Whole:Whole(int i,int j,int k): two(i),one(j)date=k;/.其他函数的实现略,89,7.7 对象数组,使用类定义的一个数组:teacher T500; / 比较:int a20;此时:该数组每个元素使用不带参数的构造函数初始化;定义时,可显式调

50、用构造函数初始化每个对象;使用时,数组元素赋值。,class DATE public: DATE(int m,int d,int y); void print(); private: int month,day,year;; DATE dates4=DATE(3,25,2007), DATE(3,26,2007), DATE(3,27,2007), DATE(3,28,2007)dates0=DATE(3,25,2007);,对象数组的使用:与基本类型方式相似,可以直接调用相应对象public成员。dates0.print();for(int i=0;i4;i+)datesi.print();

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号