第二章 从结构到类的演变_第1页
第二章 从结构到类的演变_第2页
第二章 从结构到类的演变_第3页
第二章 从结构到类的演变_第4页
第二章 从结构到类的演变_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

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

文档简介

第二章从结构到类的演变主讲:冯传胜Email:fcs@2.1结构的演化2.2从结构演变一个简单的类2.3面向过程与面向对象2.4C++面向对象程序设计的特点2.5使用类和对象2.6string对象数组与泛型算法2.1结构的演化2.1.1结构发生质的演变1、函数与数据共存C++允许结构中可以定义函数,称为成员函数。struct结构名{数据成员成员函数};可以用C语言中使用结构成员的方法使用成员函数结构对象.成员函数例2.1:/*源程序*/#include<iostream>usingnamespacestd;structPoint {voidSetxy(doublea,doubleb) {x=a;y=b;} voidDisplay() {cout<<"("<<x<<","<<y<<")"<<endl;} doublex,y; };voidmain() {Pointa; a.Setxy(10.6,18.5); a.Display(); cout<<"("<<a.x<<","<<a.y<<")"<<endl; };/*运行结果*/(10.6,18.5)(10.6,18.5)结构定义:struct结构名 {数据成员 成员函数};成员函数使用:结构对象.成员函数struct结构中的成员是公有的(public)2、封装性如果在定义结构时,将数据成员使用private关键字,则产生封装性。例2.2:/*源程序*/#include<iostream>usingnamespacestd;structPoint {public: voidSetxy(doublea,doubleb) {x=a;y=b;} voidDisplay() {cout<<"("<<x<<","<<y<<")"<<endl;} private: doublex,y; };voidmain() {Pointa; a.Setxy(10.6,18.5); a.Display(); cout<<"("<<a.x<<","<<a.y<<")"<<endl; };正确!错误!对于私有数据成员,必须通过公有的成员函数访问,这就称为数据的封装性。private的使用使结构具有“类”的特性。结构中默认成员为public,而类中默认成员为private。2.1.2使用构造函数初始化结构的对象结构中private的使用使其具有封装性,所以不能像C语言中那样使用初始化列表对结构对象进行初始化。为此我们可以设计两个特殊的成员函数来进行初始化。两个函数的名字与结构同名,其原型为Point()Point(double,double)两函数为重载函数。专门用于对象的初始化,称为构造函数。例2.3:构造函数。/*源程序*/#include<iostream>usingnamespacestd;structPoint {public: Point(){}; Point(doublea,doubleb) {x=a;y=b;} voidSetxy(doublea,doubleb) {x=a;y=b;} voidDisplay() {cout<<"("<<x<<","<<y<<")"<<endl;}

private:

doublex,y; };voidmain() {Pointa; Pointb(1.0,2.0); a.Setxy(10.6,18.5); a.Display(); b.Display(); };使用构造函数!构造函数的使用方法:构造函数名对象名(初始化参数);2.2从结构演变一个简单的类利用关键字class(类)代替struct(结构)就是一个标准的类。例2.4/*源程序*/#include<iostream>usingnamespacestd;classPoint {public: Point(){}; Point(doublea,doubleb) {x=a;y=b;} voidSetxy(doublea,doubleb) {x=a;y=b;} voidDisplay() {cout<<"("<<x<<","<<y<<")"<<endl;}

private:

doublex,y; };Point类Point类示意图voidmain(){Pointa;Pointb(1.0,2.0);a.Setxy(10.6,18.5);a.Display();b.Display(); };类的使用与结构相同。如,voidmain() {Pointa; Pointb(1.0,2.0); a.Setxy(10.6,18.5); a.Display(); b.Display(); };类名Point具有属性x和y提供的操作:构造函数PointSetxy用来给对象赋值Display用来输出x和yPoint类示意图2.3面向过程与面向对象面向过程不必要了解计算机的内部逻辑,而把精力主要集中在对如何求解问题的方法逻辑和过程上,通过编写程序把解决问题的步骤告诉计算机。例2.5:输入三角形3个顶点的坐标,计算3边长的过程算法描述。输入三个顶点的坐标数据(6个数据)计算两个顶点间的距离得到连长输出三个边长C语言中的函数是功能的抽象。有利于结构化程序设计和模块化设计,适合于大型程序的开发。解决了大系统多文件的组织与管理。C++是混合型语言,可用于面向过程软件的开发。当软件太复杂,结构化程序设计不能满足要求。人们分析问题思考方式的不一致全局变量的大量存在面向过程存在的问题。要求开发人员按计算机的结构去思考,而不是按要解决的问题的结构去思考。开发人员必须在机器模型(解空间)和实际问题模型(问题空间)之间进行对应。面向过程的方法充满“变数”。面向对象相对于过程,对象是稳定的。在面向对象程序设计中,可以将一组密切相关的函数统一封装在一个对象中,从而可以合理、有效地避免全局变量的使用。对象是功能抽象和数据抽象的统一。面向对象的程序设计方法不是以函数过程和数据结构为中心,而是用对象代表求解问题的中心环节。例2.6:输入三角形的3个顶点坐标,计算3条边的长度的面向对象的算法描述。问题以“点”对象为中心环节。边长可以看作两点对象之间了距离。设计Point类:算法设计:设计Point类创建3个点对象PointA(x1,y1);PointB(x2,y2);PointC(x3,y3);计算边长:AB:A.Getlength(B);BC:B.Getlength(C);AC:A.Getlength(C);输出三边长:AB,BC,AC类名Point具有属性x和y提供的操作:构造函数PointGetlength求两点对象之间的距离Getx得到点的x坐标Gety得到点的y坐标软件开发是对给定问题求解的过程,包含两部:认识和描述。问题域:软件开发者将被开发的整个业务范围称作“问题域”。认识:就是通过人的思维,对该问题域客观存在的事物以及对所要解决的问题产生正确的认识和理解,包括弄清事物的属性、行为及其彼此之间的关系并找出解决问题的方法。描述:是指人们用一种语言把对问题域中事物的认识、对问题及其解决方法的认识描述出来。最终描述成一种能被计算机读得懂的语言,即编程语言。客观事物(问题域)缝隙自然语言面向对象语言面向过程语言汇编语言机器语言计算机人们对问题认识的差距产生“缝隙”。语言发展趋势原来的鸿沟语言的发展使鸿沟逐渐变窄2.4C++面向对象程序设计的特点与传统的程序设计方法相比,面向对象程序设计具有抽象、封装、继承和多态性等关键要素。2.4.1对象描述对象的三要素:对象名、属性、操作。对象名:用来标识一个具体对象。属性:用数据来表示对象的属性,一个属性就是描述对象静态特征的一个数据项。操作:是描述对象动态特征(行为)的一个函数序列(用函数实现操作),也称为方法或服务。数据称为“数据成员”,函数称为“成员函数”。C++中的对象是系统中用来描述客观事物的一个实体,要构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的成员函数构成。对象名属性1属性2…属性n操作1操作2…操作n例2.7:用简单对象表示平面上的两个坐标点:A(3.5,6.4),B(8.5,8.9)。AX(3.5)Y(6.4)Display();Setxy();Move();BX(8.5)Y(8.9)Display();Setxy();Move();2.4.2抽象和类抽象是一种从一般的观点看待事物的方法,即集中于事物的本质特征,而不是具体细节或具体实现。可以从一组对象的共同特征进一步抽象出来从而形成“类”的概念。类由类名、一组属性、一组操作组成。类的属性只是性质的说明,对象的属性才是具体数据。如,从上例中A,B两点抽象出来的点类,如右上图。Pointfloatx;floaty;Display();Setxy();Move();类名属性1属性2…属性n操作1操作2…操作n在抽象的过程中用到“归纳法”和“演绎法”:归纳法:从特殊到一般,即“归类”。演绎法:从一般到特殊,即“分类”。类与对象:对象由一些属性和操作组成,而这些属性和操作描述了对象的内部细节。类是具有相同属性和操作的一组对象集合,它为属于该类的全部对象提供了统一的抽象描述。类给出了属于该类的全部对象的抽象定义,而对象则是符合这种定义的实体。2.4.3封装对象由属性与操作组成。属性只能通过操作存取操作分内部操作和外部操作外部操作提供消息接口对象内部数据结构的不可访问性称为信息(数据)隐藏。数据封装减少了出错的可能性。类中封装是通过存取权限实现的。类的属性和操作分为私有的(private)和公有的(public)两种类型。属性1属性2…属性n内部操作1内部操作2…内部操作n外部操作1外部操作2…外部操作n对象名2.4.4继承继承是一个类可以获得另一个类的特性的机制,继承支持层次概念。低层的类只须定义特定于它的特征,而共享高层类中的特征。水果苹果桔子香蕉红富士红香蕉2.4.5多态性不同的对象可以调用相同名称的函数,但可导致完全不同的行为的现象称为多态性,程序中只须一般形式的函数调用,函数的实现细节留给接受函数调用的对象。有利于提高解决复杂问题的能力。如“+”7+81.1+2.22.5使用类和对象本节介绍C++标准程序库提供的string和complex类。2.5.1使用string对象C++的string类很复杂,在这里我们只给出它的部分属性和操作。字符串str是string类的属性函数string是构造函数,有多个函数find检索子串函数size计算并返回字符串的长度函数substr返回字符串中的子串stringstrstring();findsizesubstr使用头文件<string>,即应有语句#include<string>string对象的构造stringstr=“abc”;stringstr(“abc”);注意:字符串是“”括起来的字符序列。stringstr=‘a’; //错误stringstr=“a”; //正确函数size的应用string对象名.size()字符串连接运算符“+”str+“a” //字符串之间的连接Str+‘a’ //字符串与字符之间的连接例2.8:演示使用string对象及初始化的例子。#include<iostream>#include<string>usingnamespacestd;voidmain() {stringstr1("Wearehere!"); stringstr2="Whereareyou?"; cout<<str1[0]<<str1[11]<<","<<str1<<endl; cout<<str2[0]<<str1[13]<<","<<str2<<endl; cout<<"Pleaseinputaword:"; cin>>str1; cout<<"lengthofthe"<<str1<<"is"<<str1.size()<<"."<<endl; }2.5.2使用string类的典型成员函数实例对象调用成员函数的语法可表示如下:对象名称.成员函数(参数(可供选择的消息内容))函数size没有参数如,str1.size()函数substr有两个参数第一个参数:截取串在字符串中的起始位置(从0开始)第二个参数:截取串的长度(可以超出字符串的长度)如,str2=str1.substr(3,3);函数find有两个参数返回子串在字符串中的位置,找不到返回-1第一个参数:要查找的子串第二个参数:开始查找的位置(缺省时默认为0)如,inti=str1.find(“are”,0);函数getline用来从流cin中读出输入的一行给string类的对象,如stringstr;getline(cin,str,‘\n’);功能为从键盘上读取一串字符给对象str,以回车结束例2.9:将美国日期转换为国际日期的例子。如输入“December29,2008”,则输出“28December2008”思路:寻找月份。在第一个空格之前为月份,用find函数查找空格位置。寻找日子。在第一个空格之后到“,”之前为日子,用find函数查找“,”,用substr函数取日子数据。寻找年份。取剩余子串为年份(注意“,”之后有一空格)。/*源程序*/#include<iostream>#include<string>usingnamespacestd;voidmain(){ stringDate; cout<<"InteradateinAmericanformat:"; getline(cin,Date,'\n'); intx=Date.find(""); stringMonth=Date.substr(0,x); inty=Date.find(","); stringDay=Date.substr(x+1,y-x-1);

stringYear=Date.substr(y+2,Date.size()-y-2); stringNewDate=Day+""+Month+""+Year; cout<<"Originaldate:"<<Date<<endl; cout<<"Converteddate:"<<NewDate<<endl;}InteradateinAmericanformat:Dec22,2003Originaldate:Dec22,2003Converteddate:22Dec20032.5.3使用complex对象用来定义复数对象使用时应包含头文件<complex>,即#include<complex>complex对象有两个初始值,用构造函数来实现多值处理。complex类是一个模板类,所谓模板,就是指它可以定义多种数据类型的复数对象。如实部与虚部为整数实部与虚部为实数,等其类型可在complex后面加“<type>”来说明。complex对象的定义complex<type>对象名(实部,虚部);complexreal;image;complex();real();imag();例2.10:演示使用complex和string对象及初始化的例子。/*源程序*/#include<iostream>#include<string>#include<complex>usingnamespacestd;voidmain(){ complex<int>num1(2,3); complex<float>num2(2.5,3); stringstr1("Realpartis:"); stringstr2="Imagepartis:"; cout<<str1<<num1.real()<<","<<str2<<num1.imag()<<endl <<str1<<num2.real()<<","<<str2<<num2.imag()<<endl; }Realpartis:2,Imagepartis:3Realpartis:2.5,Imagepartis:32.5.4使用对象小节类是一类对象的抽象。类的属性称为数据成员。如string类的str属性,comple类的实部与虚部。通过属性的值来区分对象。通过成员函数(操作方法)对数据成员(属性)进行操作。complex类是一个模板类,即定义复数类时与类型无关,只有定义对象时才指定实部与虚部的类型。这就象作了一个烧铸勺子的模具,具体用什么材质(铁、铝等)做具体的勺子时才确定。2.6string对象数组与泛型算法第一章中介绍的针对数组的泛型算法同样适用于string类。使用时应请注意以下两点:泛型算法中的find函数与string类中find成员函数的区别。string类中有一个swap函数来交换两个对象的属性。如,stringstr1(“We”),str2(“You”);str1.swap(str2);上面语句的作用是将str1和str2的属性交换,所以与以下语句等效str2.swap(str1);例2.11:演示string对象的例子。#include<iostream>#include<string>#include<algorithm>usingnamespacestd;voidmain(){ stringstr1("Wearehere!"),str2=str1; reverse(&str1[0],&str1[0]+12); cout<<str1<<endl; copy(&str1[0],&str1[0]+12,&str2[0]); cout<<str2<<endl; reverse_copy(&str2[0],&str2[0]+12,ostream_iterator<char>(cout)); cout<<endl;}!ereheraeW!ereheraeWWearehere!从上面例子可以看出,当使用string对象中的地址时很麻烦,str1不再是一个地址,而是一个对象名,引用字符串第一个字符的地址不得不用&str1[0]。String类提供两个成员函数来标识string对象中字符串的存储空间:begin()函数end()函数字符串的存储区间为:[begin,end)如,对于str1Weareher!estr1.begin()str1.end()可见,string对象的字符串中不用“\0”作为结束标志,而char定义的字符串中自动加“\0”作为结束标志。例2.12:用成员函数表示存储区间的例子。#include<iostream>#include<string>#include<algorithm>#include<functional>usingnamespacestd;voidmain(){ stringstr1("wearehere!"),str2=str1; reverse(str1.begin(),str1.en

温馨提示

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

评论

0/150

提交评论