理学类和对象的概念_第1页
理学类和对象的概念_第2页
理学类和对象的概念_第3页
理学类和对象的概念_第4页
理学类和对象的概念_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

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

文档简介

编码求解下列问题编写一个程序,计算任给一个几何形体的面积和周长。几何形体可以是矩形、三角型、圆形、扇型、梯形。要求:由用户通过键盘输入要处理的几何形体,每次输入一个几何形体。输入规则是:程序输出提示信息,请用户选择要处理的几何形体的类型。如果输入字母“E”,表示要退出程序的运行根据用户选择的几何形体类型,输出提示信息,请用户输入几何形体的描述数据。例如圆形的中心点坐标和半径。要求在提示信息中说明输入数据的格式。在用户输入一个几何形体后,程序输出该几何形体的面积和周长,要求在输出中注明哪个数据是面积、哪个数据是周长。然后回到上一步,继续处理新的几何形体,直到用户选择退出程序运行为止。分析:如何解决这个问题?要定义5类数据结构,分别记录不同形状的基本数据:矩形(左上角顶点/长/宽)、三角型(三个顶点)、圆形(圆心/半径)、扇型(圆心/半径/其始边的水平角度/弧度)、梯形(四个顶点)申明5个存储空间变量每个数据类型描述一个存储空间变量的布局每个变量用来记录一种形状的基本数据编写一个main函数,外加15个普通函数.5个基本数据输入函数,分别输入一种形状的基本数据5个面积计算函数,分别计算一种形状的面积5个周长计算函数,分别计算一种形状的周长如何规划程序的结构?程序的构成要件:5个数据结构/5个变量/15个普通函数/main函数除main函数外,其他25个构成要件可以分成5组,每组对应一种形状(问题中的一个概念),包括一个数据结构(这个概念所对应实例的数据表达)一个变量(这个概念的一个实例)3个函数(问题中与这个概念相关的算法流程要求)显然,不同组之间没有任何关联良好的设计和编码应该体现分组特征组之间的无耦合特征以矩形对应的一组程序构成要件为例编码示例1:structSRectangle{ intx,y; intw,h;};SRectanglerectangle;voidrectangleInit(){ ……}intrectangleArea(){ ……}intrectanglePerimeter(){ ……}编码示例2:structSType1{ intx,y; intw,h;};……SType1variable5;……voidfun2(){ ……}……intfun8(){ ……}……intfun13(){ ……}给上面的每组程序构成要件一个名称:类及对象类:被求解问题中的一个概念的具体表达(即文字符号的描述),包括两部分成员属性:这个概念所对应实例的数据表达成员函数/方法:问题中仅与这个概念相关的那部分算法对象:某个概念在被求解问题中的一个实例,基于对应的类对这个实例的具体表达例如需要求解其面积的一个长方形类及对象:具体表达被求解问题中的某个概念,以及这个概念在被求解问题中的全部实例编码示例1明显好于编码示例2编码示例1在程序结构中的规划中体现了类及对象,当程序员考虑与矩形相关的事情时,只要关注这一个代码块一个子串rectangle,将所有只与矩形相关的程序构成要件都联系一起来了,一目了然遗憾的是,编程人员(特别是初学编程的人员)通常把注意力集中在问题分析阶段,对程序结构的规划不重视甚至完全忽视,经常出现编码示例2那样的代码用一个POINT结构来代替矩形左上角的X和Y坐标更直观,而且其他形状也面临同样的需要要发现这样一个修改所影响的函数,程序要要么记忆很好,要么只好把所有的15个函数都读一遍面向对象的编程语言C++程序的构成要件:类/类的对象/main函数类:一个数据结构,以及依赖该数据结构的一组函数属性:数据结构中的一个分量函数:在该数据结构上执行算法运算,读/写数据结构中的某个分量类的对象:用类声明的变量类中的数据结构用来说明进行内存分配类的函数规定了哪些函数可直接访问所分配的内存C++对程序构成要件的这种约束指导编程人员在分析阶段自觉揭示程序构成要件之间的关系强制编程人员在编码阶段采用类似编码示例1的方式安排程序结构(通过类的构造函数和析构函数)提示编程人员要对所分配的内存空间进行初始化,在不在需要某个存储空间时要释放仅在该空间才记录其访问信息的那些资源.比如动态分配内存空间的地址指针以矩形对应的一组程序构成要件为例编码示例3:classCRectangle{public: intx,y; intw,h; voidInit(); intArea(); intPerimeter();};CRectanglerectangle;voidCRectangle::rectangleInit(){ ……}intCRectangle::Area(){ ……}intCRectangle::Perimeter(){ ……}编码示例4:classCType1{public: intx,y; intw,h; voidfun1(); intfun2(); intfunc3();};CType1var1;voidCType1::fun1(){ ……}intCType1::fun2(){ ……}intCType1::fun3(){ ……}抽象和封装抽象:通过类,表达事物中与当前问题相关的那些内容,而且将所涉及的数据(类的成员属性)和算法流程(类的成员函数)显式的联系在一起封装:通过类和对象,将事物的相关数据的存储实现细节和算法流程的实现细节隐藏起来,对外只展示其他程序模块所关心的结果例如矩形左上角顶点的存储可以直接用X和Y坐标,也可以用一个POINT结构.具体的实现方式只影响在该类3个相关函数的编码实现,与这三个成员函数的接口都没有关系.计算三角行的面积,可以用底边和高算,也可以用两条边及其夹角算.计算方法的选择只关系到面积计算函数的编码实现,与该函数的接口无关C语言使用结构化程序设计:

程序=数据结构+算法程序由全局变量以及众多相互调用的函数组成。算法以函数的形式实现,用于对数据结构进行操作。结构化程序设计main()Sub1()Sub2()Sub3()Sub1_1()Sub3_1()Sub3_2()…var1var2var3…变量:结构化程序设计的程序模式:从编程语言方面,不提供对程序结构规划的指导和提示信息对于经验丰富的高级程序员,会精心规划程序的结构,在程序中会采用类似编码示例1这样的模块划分对于普通编程人员,容易忽视对程序结构的规划.结构化程序设计结构化程序设计没有“封装”和“隐藏”的概念。要访问某个数据结构中的某个变量,就可以直接访问,那么当该变量的定义有改动的时候,就要把所有访问该变量的语句找出来修改,十分不利于程序的维护、扩充。难以查错,当某个数据结构的值不正确时,难以找出到底是那个函数导致的。结构化程序设计面向对象的程序设计方法:将某类客观事物共同特点(属性)归纳出来,形成一个数据结构(可以用多个变量描述事物的属性);将这类事物所能进行的行为也归纳出来,形成一个个函数,这些函数可以用来操作数据结构(这一步叫“抽象”)。然后,通过某种语法形式,将数据结构和操作该数据结构的函数“捆绑”在一起,形成一个“类”,从而使得数据结构和操作该数据结构的算法呈现出显而易见的紧密关系,这就是“封装”。面向对象的程序设计main()面向对象的程序模式:class1var1Sub1()Sub1_1()class2var2Sub2()class3var3Sub3()Sub3_1()Sub3_2()从编程语言的语法结构层面,要求对程序的结构进行规划当对问题分析后,同一分析结果,不同程序员的编码差距要小很多,类似编码示例3与编码示例4的差别

采用面向对象的程序设计语言写一个程序,输入矩形的长和宽,输出面积和周长。比如对于“矩形”这种东西,要用一个类来表示,该如何做“抽象”呢?矩形的属性就是长和宽。因此需要两个变量,分别代表长和宽。一个矩形,可以有哪些行为呢(或可以对矩形进行哪些操作)?矩形可以有设置长和宽,算面积,和算周长这三种行为(当然也可以有其他行为)。这三种行为,可以各用一个函数来实现,他们都需要用到长和宽这两个变量。从客观事物抽象出类的例子将长、宽变量和设置长,宽,求面积,以及求周长的三个函数“封装”在一起,就能形成一个“矩形类”。长、宽变量成为该“矩形类”的“成员变量”,三个函数成为该类的“成员函数”。

成员变量和成员函数统称为类的成员。实际上,“类”看上去就像“带函数的结构”。从客观事物抽象出类的例子从客观事物抽象出类的例子classCRectangle{

public: intw,h; intArea(){ returnw*h; } intPerimeter(){ return2*(w+h); } voidInit(intw_,inth_){ w=w_;h=h_; }};//必须有分号注:此处将类成员函数的实现直接写在类的定义中,在语法上是允许的.但建议大家养成在类定义外实现其成员函数的习惯.避免在考察类的成员时,被成员函数的实现代码干扰注意力从客观事物抽象出类的例子intmain(){ intw,h; CRectangler;//r是一个对象

cin>>w>>h; r.Init(w,h); cout<<r.Area()<<endl<<r.Perimeter(); return0;}通过类,可以定义变量。类定义出来的变量,也称为类的实例,就是我们所说的“对象”。C++中,类的名字就是用户自定义的类型的名字。可以象使用基本类型那样来使用它。CRectangle就是一种用户自定义的类型。对象的内存分配和结构变量一样,对象所占用的内存空间的大小,等于所有成员变量的大小之和。每个对象各有自己的存储空间。一个对象的某个成员变量被改变了,不会影响到另一个对象。

如何使用类的成员变量和成员函数用法1:对象名.成员名

CRectangler1,r2; r1.w=5; r2.Init(5,4);Init函数作用在r2上,即Init函数执行期间访问的w和h是属于r2这个对象的,执行r2.Init不会影响到r1。用法2.指针->成员名

CRectangler1,r2; CRectangle*p1=&r1; CRectangle*p2=&r2; p1->w=5; p2->Init(5,4);//Init作用在p2指向的对象上

如何使用类的成员变量和成员函数用法3:引用名.成员名

CRectangler2;CRectangle&rr=r2; rr.w=5; rr.Init(5,4);//rr的值变了,r2的值也变voidPrintRectangle(CRectangle&r){ cout<<r.Area()<<","<<r.Perimeter();}CRectangler3;r3.Init(5,4);PrintRectangle(r3);引用的概念类型名&引用名=某变量名;此种写法就定义了一个引用,并将其初始化为引用某个变量。某个变量的引用,和这个变量是一回事,相当于该变量的一个别名。intn=4;int&r=n;r=4;cout<<r;//输出4cout<<n;//输出4n=5;cout<<r;//输出5

定义引用时一定要将其初始化成引用某个变量,不初始化编译不过。引用只能引用变量,不能引用常量和表达式。C语言中,要写交换两个整型变量值的函数,只能通过指针。voidswap(int*a,int*b){ inttmp; tmp=*a;*a=*b;*b=tmp;}intn1,n2;swap(&n1,&n2);//n1,n2的值被交换引用的作用有了引用后:voidswap(int&a,int&b){ inttmp; tmp=a;a=b;b=tmp;}intn1,n2;swap(n1,n2);//n1,n2的值被交换引用的作用函数的返回值可以是引用,如:#include<iostream>usingnamespacestd;intn=4;int&SetValue(){ returnn;}intmain(){ SetValue()=40; cout<<n; return0;}该程序输出结果是40引用作为函数的返回值类的成员函数的另一种写法成员函数体和类的定义分开写。classCRectangle{ public: intw,h; intArea();//成员函数仅在此处声明

intPerimeter(); voidInit(intw_,inth_);}; intCRectangle::Area(){ returnw*h; } intCRectangle::Perimeter() { return2*(w+h); } voidCRectangle::Init(intw_,inth_){ w=w_;h=h_; }CRectangle::说明后面的函数是CRectangle类的成员函数,而非普通函数。那么,一定要通过对象或对象的指针或对象的引用才能调用。类的成员函数的另一种写法对象成员的访问权限在类的定义中,用下列权限关键字来说明对象成员的访问权限:private:

私有成员,只能在成员函数内访问public:

公有成员,可以在任何地方访问protected:

保护成员,以后再说以上三种关键字出现的次数和先后次序都没有限制。定义一个类classclassName{

private:

私有属性和函数

public:

公有属性和函数

protected:

保护属性和函数};说明类成员的可见性如过某个成员前面没有上述关键字,则缺省地被认为是私有成员。classMan{ intnAge;//私有成员

charszName[20];//私有成员public: voidSetName(char*szName){ strcpy(Man::szName,szName); }};对象成员的访问权限在类的成员函数内部,能够访问:当前对象的全部属性、函数;同类其它对象的全部属性、函数。在类的成员函数以外的地方,只能够访问该类对象的公有成员。对象成员的访问权限classCMan{private: charszName[30];//名字public: floatheight,weight;//保存一个人的身高和体重信息

voidsetName(char*name); voidFunc1(CManman); ~CMan();//析构函数};voidCMan::setName(char*name){ CManman; strcpy(man.szName,"Lily");//ok,此种访问方式可行

strcpy(szName,name);//ok}voidCMan::Func1(CManman){ cout<<man.szName;//ok}CMan::~CMan(){}intmain(){ CManman1,man2;

strcpy(man1.szName,“Tom1234567889”);//错,不能访 //问私有成员

man1.setName("Tom12345678909887");//ok man1.height=5;//ok return0; }设置私有成员的目的是强制对成员变量的访问一定要通过成员函数进行,那么以后成员变量的类型等属性修改后,只需要更改成员函数即可。否则,所有直接访问成员变量的语句都需要修改。设置私有成员的机制,叫“隐藏”如果将上面的程序移植到内存空间紧张的手持设备上,希望将szName改为charszName[5],若szName不是私有,那么就要找出所有类似 strcpy(man1.szName,”Tom1234567889”);这样的语句进行修改,以防止数组越界。这样做很麻烦。如果将szName变为私有,那么程序中就不可能出现(除非在类的内部) strcpy(man1.szName,”Tom1234567889”);这样的语句,所有对szName的访问都是通过成员函数来进行,比如:

man1.setName(“Tom12345678909887”);那么,就算szName改短了,上面的语句也不需要找出来修改,只要改setName成员函数,在里面确保不越界就可以了。函数重载一个或多个函数,名字相同,然而参数个数或参数类型互不相同,这叫做函数的重载。如: intMax(doublef1,doublef2){} intMax(intn1,intn2){} intMax(intn1,intn2,intn3){}函数重载使得函数命名变得简单。函数的缺省参数:C++中,写函数的时候可以让参数有缺省值,那么调用函数的时候,若不写参数,参数就是缺省值。voidfunc(intx1=2,intx2=3){}func();//等效于func(2,3)func(8);//等效于func(8,3)func(,8);//不行函数参数可缺省的目的在于提高程序的可扩充性。即如果某个写好的

温馨提示

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

评论

0/150

提交评论