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

下载本文档

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

文档简介

第二章从结构到类的演变C++中的结构与C中的结构已经发生了质的变化。本章通过实例,简要说明结构如何向类变化,从而引入对象和类的知识。然后介绍c++标准程序库提供的两个典型的类。通过使用这两个类,进一步熟悉类和对象,为学习面向对象编程打下基础。12.1结构的演化2.1.1结构发生质的改变1、定义:由相互关联的相同或者不同数据类型的数据组成的有机整体。是一种构造数据类型。2、定义格式struct

[结构体名]{

类型标识符成员名1;类型标识符成员名2;…………….};例:structstudent{charname[20];intage;charsex;};一、c中的结构23、结构体变量的定义结构名称变量名称例如:structstudent{

charname[20];intage;charsex;};studentstu1,stu2;只有在定义了结构体变量后系统才为其分配内存。定义结构体类型定义结构体变量34、结构体变量的引用结构体变量不能整体引用,只能引用变量成员形式:结构体变量名.成员名

例如:structstudent{

charname[20];intage;charsex;};studentstu1,stu2;stu1.age=25;stu1.sex=‘F’;正确的成员使用4#include<iostream>usingnamespacestd;voidmain(){structstudent{charname[20];intage;charsex;};studenta;strcpy(,"zhang");a.age=12;a.sex='m';cout<<<<","<<a.age<<","<<a.sex<<endl;}strcpy():字符串复制函数。字符串的赋值不能使用“=”,只能使用函数来完成。5C++允许结构中可以定义函数,这些函数成为成员函数。如果将原来的结构成员称为数据成员的话,结构的定义形式为:struct结构名{数据成员成员函数};二、函数与数据共存(理解)定义结构体对象后,结构体对象自动具有结构体的数据成员和成员函数。可以通过以下形式来使用:

对象名.成员函数()对象名.数据成员

6structstudent{charname[20];intage;charsex;

voideat(){ cout<<"吃饭了"<<endl; cout<<"喝汤了"<<endl; cout<<"吃饱了"<<endl;}};structstudent{charname[20];intage;charsex;};//结构中只有数据//成员函数//数据成员函数与数据共存7voidmain(){ students1; cout<<"name:";cin>>; cout<<"age:";cin>>s1.age; cout<<"sex:";cin>>s1.sex; cout<<<<""<<s1.age<<endl; s1.eat();}structstudent{charname[20];intage;charsex;

voideat(){ cout<<"吃饭了"<<endl; cout<<"喝汤了"<<endl; cout<<"吃饱了"<<endl;}};8structPoint{doublex,y;voidSetxy(doublea,doubleb){x=a;y=b;}voidDisplay(){cout<<x<<"\t"<<y<<endl;}};//数据成员//成员函数函数与数据共存9#include<iostream>//lt2_1.cppusingnamespacestd;structPoint{ doublex,y; voidSetxy(doublea,doubleb) {x=a;y=b;} voidDisplay() {cout<<x<<"\t"<<y<<endl;}};voidmain(){ Pointa; a.Setxy(10.2,5.3); a.Display();cout<<a.x<<"\t"<<a.y<<endl; a.x=20.5; a.y=15.6;a.Display(); cout<<a.x<<"\t"<<a.y<<endl; }//定义结构对象a//使用成员函数,给数据成员赋值//直接使用数据成员//使用成员函数,显示数据成员的值//直接使用数据成员,并给其赋值10.2 5.310.2 5.320.5 15.620.5 15.6//数据成员10#include<iostream>//lt2_1.cppusingnamespacestd;structPoint{ doublex,y; voidSetxy(doublea,doubleb) {x=a;y=b;} voidDisplay() {cout<<x<<"\t"<<y<<endl;}};voidmain(){ Pointa; a.Setxy(10.2,5.3); a.Display();cout<<a.x<<"\t"<<a.y<<endl; a.x=20.5; a.y=15.6;a.Display(); cout<<a.x<<"\t"<<a.y<<endl; }由此例看出,可以通过结构的成员函数使用数据成员,a.Setxya.Displaya.xa.y也可以直接使用数据成员。这称作结构Point的公有(publie)性质11三、封装性若定义结构体时,使用了private关键字,则产生封装性。structPoint{doublex,y;voidSetxy(doublea,doubleb){x=a;y=b;}voidDisplay(){cout<<x<<"\t"<<y<<endl;}};public:在结构体中,成员默认为public性质。private:public:12#include<iostream>usingnamespacestd;structPoint{private:doublex,y;

public:voidSetxy(doublea,doubleb){x=a;y=b;}voidDisplay(){cout<<x<<"\t"<<y<<endl;}};voidmain(){Pointa;a.Setxy(10.2,5.3);a.Display();cout<<a.x<<"\t"<<a.y<<endl;a.x=20.5;a.y=15.6;cout<<a.x<<"\t"<<a.y<<endl;a.Display();}voidmain(){Pointa;a.Setxy(10.2,5.3);a.Display();cout<<a.x<<"\t"<<a.y<<endl;a.x=20.5;a.y=15.6;cout<<a.x<<"\t"<<a.y<<endl;a.Display();}//使用公有的成员函数error:'x':cannotaccessprivatememberdeclaredinclass'Point'试图使用私有的数据成员私有的数据成员必须通过公有的成员函数才能使用,这就称为数据的封装性。这就变成了具有类的性质的结构使用了private关键字,则产生封装性13#include<iostream>usingnamespacestd;structPoint{private:doublex,y;

public:voidSetxy(doublea,doubleb){x=a;y=b;}voidDisplay(){cout<<x<<"\t"<<y<<endl;}};

voidmain(){Pointa;a.Setxy(10.2,5.3);a.Display();}10.2 5.314由上可知:在定义结构时,若使用了private则产生封装性,表示成员为私有的,只能在结构体内部通过公有成员函数使用。若未添加private则表示默认为public。即:私有成员不可通过

对象名.数据成员对象名.成员函数()形式来使用也就是说封装之后不可通过对象名使用private成员15四、从结构演变一个简单的类使用关键字class代替struct,就是一个标准的类。structPoint{private:doublex,y;public:voidSetxy(doublea,doubleb){x=a;y=b;}voidDisplay(){cout<<x<<"\t"<<y<<endl;}};结构class类使用类产生对象的方式和结构一样。(如:)16#include<iostream>usingnamespacestd;classPoint{private:doublex,y;

public:voidSetxy(doublea,doubleb){x=a;y=b;}voidDisplay(){cout<<x<<"\t"<<y<<endl;}};

voidmain(){Pointa;a.Setxy(10.2,5.3);a.Display();}10.2 5.317课程回顾1、在结构中,没有使用private定义的成员,默认为

。public2、私有的数据成员,必须通过公有的成员函数才能使用,这称为数据的

性。封装3、与结构不同的是,类使用

关键字来定义,其成员默认的性质是

。privateclass18类图的表示类名属性/成员变量操作(功能)/成员函数PointXySetxyDisplay19五、使用构造函数初始化对象因为类具有封装性,所以不能使用“对象名.数据成员”的方式对数据成员进行初始化。所以为类Point设计两个专门用于初始化的函数。其原型如下:因为类是一种数据类型,在声明一个类时系统并不会为其分配内存空间,所以在定义类中的数据成员时,不能对其进行初始化。classPoint{private:doublex=10.5,y=5.6;public:voidSetxy(doublea,doubleb){x=a;y=b;}voidDisplay(){cout<<x<<"\t"<<y<<endl;}};错误Point();Point(double,double);若定义的函数与某个已定义函数重名而参数类型或个数不同,则称为

。函数重载在定义类时,与类同名的函数称为构造函数。其作用是专门用于初始化对象。20classPoint{private:doublex,y;public:

Point(){};

Point(doublea,doubleb){x=a;y=b;}voidSetxy(doublea,doubleb){x=a;y=b;}voidDisplay(){cout<<x<<"\t"<<y<<endl;}};voidmain(){Pointa;a.Setxy(10.2,8.9);a.Display();}#include<iostream>usingnamespacestd;//定义对象a//设置a的数据成员//显示a的数据成员Pointa(10.2,8.9);a.Display();当对象在内存中产生时会自动调用构造函数212.3面向过程和面向对象简单了解对象的含义221、面向过程的求解步骤:例题:给出三角形三个顶点坐标,计算三边长,并输出。(1)输入三个顶点坐标A(x1,y1),B(x2,y2),C(x3,y3)(2)计算(x1,y1)和(x2,y2)距离AB(3)计算(x1,y1)和(x3,y3)距离AC(4)计算(x2,y2)和(x3,y3)距离BC(5)输出三个距离AB、AC、BC23题解:lt2_6.cpp#include<iostream>#include<cmath>usingnamespacestd;voidmain(){

}24voidmain(){doublex1,y1,x2,y2,x3,y3;doubleAB,AC,BC;cout<<"请输入A点的坐标(x1,y1)";cin>>x1>>y1;cout<<"请输入B点的坐标(x2,y2)";cin>>x2>>y2;cout<<"请输入C点的坐标(x3,y3)";cin>>x3>>y3;AB=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));AC=sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3));BC=sqrt((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3));cout<<"AB的距离:"<<AB<<endl;cout<<"AC的距离:"<<AC<<endl;cout<<"BC的距离:"<<BC<<endl;}//声明变量252、面向对象的求解步骤(给出三角形三个顶点坐标,计算三边长,并输出)设计类:将点设计为一个类Point,并提供相关的属性和操作一个点对象:※应能存放x,y坐标;※能在定义时给出x,y值。※能设置点的x,y值;※能知道对象中存放的x,y坐标值※能计算点间距离,Pointx:doubley:doublePoint()Setxy(double,double)Getx()Gety()Getlength()26Pointx:doubley:doublePoint()Setxy(double,double)Getx()Gety()Getlength()classPoint{private:doublex,y;public:Point(){};Point(doublea,doubleb){……}

voidSetxy(doublea,doubleb){……}doubleGetx(){……}doubleGety(){……}doubleGetlength(Pointb){……}};27#include<iostream>#include<cmath>usingnamespacestd;classPoint{……};voidmain(){doubleAB,AC,BC;

Pointa(2.5,3.6),b(4.5,3.6),c(3.5,5.6); AB=a.Getlength(b); AC=a.Getlength(c); BC=b.Getlength(c); cout<<"AB的距离:"<<AB<<endl; cout<<"AC的距离:"<<AC<<endl; cout<<"BC的距离:"<<BC<<endl;}定义对象同时给出坐标(构造函数初始化方式)计算距离282.4C++面向对象程序设计特点操作:是对象动态特征的一个函数序列,用函数来实现,也称方法或服务。称为成员函数。和传统的程序设计方法相比,面向对象的程序设计具有抽象、封装、集成和多态性等关键要素。一、对象C++中对象是描述客观事物的一个实体,是构成系统的基本单位。可以使用对象名、属性和操作三要素来描述一个对象。对象名:用来标识一个具体对象,属性:就是描述对象静态特征的一个数据项,用数据来表示,称为数据成员。29操作1操作2……操作n属性1属性2……属性n对象名对象的结构图30二、抽象和类如果把程序看作是由一组抽象的对象组成的,然后将一组对象的共同特征抽象出来,就形成了“类”的概念。类由类名、一组属性和一组操作3部分构成类的属性:是性质的说明。对象才具有具体的数据,具体的属性类的操作:是行为的定义31类是具有相同属性和操作的一组对象的集合,它为属于该类的全部对象提供统一描述,内部主要包括:属性和操作两部分。※类与对象的关系:对象是由一些属性和操作构成的。对象属性和操作描述对象内部细节。类的作用是定义对象。

c++中将对象称做类的实例怎样理解“一个类的所有对象具有相同的属性”?是指属性的个数、名称、数据类型相同,各个对象的属性值则可以互不相同,并且随着程序的执行而变化。32一个对象的属性和操作是紧密结合的,对象的属性只能由这个对象的操作来存取,对象的操作分为内部操作和外部操作,内部操作只提供对象内部其他操作使用,不对外提供。外部操作提供一个消息接口,通过这个接口接收对象外部的消息并为之提供操作(服务)。三、封装33对象内部数据的不可访问性称为数据隐藏,封装给数据提供了与外界联系的接口,无论是谁,只有通过这些接口,使用规范的格式,才能访问内部数据。封装就是把对象的属性和操作结合成一个独立的系统单位,并尽可能隐藏对象的内部细节。封装在类中是通过存取权限(如私有的:private、公有的:public)实现的。34继承是一个类获得另一个类的特性的机制。继承支持层次概念四、继承(第6章)35不同对象可以调用同名函数,但可导致完全不同的行为的现象称为多态性。例如除法运算/3/23.0/2五、多态性(第8章)362.5使用类和对象2.5.1使用string对象类名类的属性用于存放字符串类的操作/方法/成员函数C++标准程序库提供了string类和complex类。本节通过这两个类了解类和对象的使用。37该类是C++语言中的内部预定义类,要在程序中使用该类时必须添加头文件#include<string>38一、string对象的定义格式:string对象名如:stringstr1,str2;二、string对象的初始化string对象隶属于string类,所以必须用双引号括起来的字符串进行初始化。391、定义的同时初始化格式:string对象名(初始值)string对象名=初始值如:stringstr1(“hello,”);stringstr2=“world”stringstr3=‘world’;stringstr4=‘a’;正确错误正确初始化的string对象,可以以数组的形式使用对象中的字符串。str1[0]的值是?str2[0]的值是?‘h’‘w’40string对象使用类似字符数组&s1[0]表示??&s1[0]+5表示??但s1对象名不表示地址,数组名表示地址412、从键盘接收字符串给string类对象赋值。格式:getline(cin,对象名,结束字符)第三个参数是字符串的结束符,也就是当getline遇到这个结束符时,就不在接受输入了。系统默认为回车符’\n’。如:stringstr;getline(cin,str,’\n’);cout<<str<<endl;如果输入:输出:(1)使用getline从流cin中读出字符串给string类的对象。遇指定字符结束。422、从键盘接受字符串给string类对象赋值。(2)使用cin读入一个字符串给string类对象赋值,遇空格、回车、tab键结束。格式:cin>>对象名如:stringstr;getline(cin,str,’\n’);cout<<str<<endl;如:stringstr;cin>>str;cout<<str<<endl;43三、string类常用的几个方法(成员函数)1、size():求对象的长度。格式:对象名.成员函数名例:stringstr=“aboy”;cout<<str.size()<<endl;则输出结果为:544例题:请分析一下程序结果(lt2_7.cpp)#include<iostream>#include<string>usingnamespacestd;voidmain(){stringstr="aboy";intn=0,i=0;while(str[i]!='\0'){ n++; i++;}cout<<"n:"<<n<<endl;cout<<"size:"<<str.size()<<endl;}求字符串长度。同size函数452、substr():求字符串的字串格式:substr(intstart,intlength)功能:从start位置开始,截取length个长度的字符串。注:(1)c++规定字符串的计数从0开始。例如:stringstr=“wishyouhappy!”;stringnewstr=str.substr(5,3);cout<<newstr<<endl;程序输出:注:(2)截取的起始位置必须位于字符串中,否则出错。注:(3)如果截取的长度大于字符串长度,则自动截取到末尾。463、find():字符串检索格式:find(要查找的字符串,开始查找的位置)功能:从指定位置开始查找所需的字符串,如果找到了,则返回字符串在主串中的位置,如果没有没到则返回-1。如果没有指定开始查找的位置,则系统默认为0。例如:strings=“howareyou?“intn=s.find(“are”,0);则n的值为:4“how”“me”0-147例题:以下程序是输入一个美国格式的日期(月日,年),(用字符串来接受日期)。然后转换成”XX年XX月XX”日的形式输出。例如:输入313,2011则输出2011年3月31日。48#include<iostream>usingnamespacestd;voidmain(){}#include<string>data,day,month,year;stringcout<<"Enterthedate(e.g.331,2011):";getline(cin,data,'\n');inti=data.find("");data.substr(0,i);month=data.find(",");intk=day=data.substr(,);stringdata.substr(,);cout<<year<<"年"<<month<<"月"<<day<<"日"<<endl;i+1k-i-1year=k+14494、+:将前后两个字符串连接strings1="you",s2="happy";cout<<s1+""+s2<<endl;注:字符串也可与单个字符常量相加。如上例中:cout<<s1+’’+s2<<endl;50#include<iostream>usingnamespacestd;voidmain(){}#include<string>data,day,month,year;stringcout<<"Enterthedate(e.g.331,2011):";getline(cin,data,'\n');inti=data.find("");data.substr(0,i);month=data.find(",");intk=day=data.substr(,);stringdata.substr(,);cout<<newdate<<endl;i+1k-i-1year=k+14如何将新格式的日期存入newdate对象中stringnewdate=year+"年"+month+"月"+day+"日";51四、string对象数组与泛型算法此前在数组中介绍的泛型算法同样适合于string类。1、swap():交换两个string对象的属性。格式:对象1.swap(对象2)例如:strings1=“me”,s2=“you”;cout<<s1<<“,”<<s2<<endl;s1.swap(s2);cout<<s1<<“,”<<s2<<endl;s2.swap(s1);另外string类还有几个成员函数。#include<iostream>#include<string>#include<algorithm>usingnamespacestd;voidmain(){ strings="china"; cout<<s<<endl; reverse(&s[0],&s[0]+5); cout<<s<<endl;}size(s);522、begin():指示第一个元素位置end():指示最后一个元素之后的位置当使用泛型算法时,如果begin不等于end,算法首先作用于begin所指元素,并将begin前进一个位置,然后作用于当前的begin所指元素,如此继续下去,直到begin等于end为止。如有:strings=“china”chinas.begin()s.end()注:使用string定义的字符串中不用字符’\0’作为结束符,使用char定义的字符串则自动在末尾加入’\0’作为结束符。53例题:以下程序是实现字符串内容的反转。#include<iostream>#include<string>#include<algorithm>usingnamespacestd;voidmain(){ strings="china"; cout<<s<<endl; reverse(&s[0],&s[0]+5); cout<<s<<endl;}s.begin()s.end()reverse(s.begin

(),s.end());54练习:以下程序是将一个字符串中的字母转换成大写输出,其他字符不变。如输入”I’m20yearsold”,则转换成I’M20YEARSOLD.#include<iostream>#include<string>usingnamespacestd;voidmain(){strings;char*p;getline(cin,s,’\n’);cout<<s<<endl;for(p=s.begin();p<s.end();p++){if(*p>=‘a’&&*p<=‘a’)*p=*p-32;}cout<<s<<endl;}//定义一个字符串对象s//定义一个指针用来遍历字符串中的每一个字符。//输入一个字符串给s//输入原字符串//转换55#include<iostream>#include<string>usingnamespacestd;voidmain(){strings;char*p;getline(cin,s,’\n’);cout<<s<<endl;for(p=s.begin();p<s.end();p++){if(*p>=‘a’&&*p<=‘a’)*p=*p-32;}cout<<s<<endl;}56#include<iostream>usingnamespacestd;voidmain(){strings1="happy!",s2(s1);}//反转s1reverse(s1.begin(),s1.end());#include<string>//原样复制s1给s2cout<<s1<<endl;!yppahcopy(s1.begin(),s1.end(),s2.begin());cout<<s1<<endl;cout<<s2<<endl;//将s1升幂排序sort(s1.begin(),s1.end());!ahppy!yppahcout<<s1<<endl;happy!#include<algorithm>练习:按要求填空57#include<algorithm>#include<iostream>usingnamespacestd;voidmain(){strings1="wearehere!",s2(s1);}练习:按要求填空//将s1中的s1[2]到s1[4]的内容逆向cout<<s1<<endl;wearehere!reverse_copy(s1.begin(),s1.end(),s2.begin());cout<<s2<<endl;//逆向复制s1给s2!ereheraewreverse(s2.begin()+2,s2.begin()+4);//输出逆向的部分内容eracopy(s2.begin()+2,s2.begin()+4,ostream_iterator<char>(cout));cout<<endl;58#include<algorithm>#include<iostream>usingnamespacestd;voidmain(){strings1="wearehere!",s2(s1);}练习:按要求填空//将s1降幂排序sort(s1.begin(),s1.end(),greater<char>());cout<<s1<<endl;wearehere!cout<<s1<<endl;wrrheeeea!//查找是否存在’e’字符,是返回1,反则返回0。#include<functional>cout<<(*find(s1.begin(),s1.end(),'e')=='e')<<endl;159作业:1、输入一个英文句子,统计其中单词的个数。2、输入一个字符串,统计其中某个字母的个数如strings=“wearehere!”,若统计字母‘e’的个数则结果为4。3、课本48页编程题1、2题60课程回顾1.在程序中可以使用

类定义存储字符串的对象。611.在C++中,封装是借助什么达到的?()A.结构B.类C.数组D.函数2.假定AA为一个类,a()为该类公有的函数成员,x为该类的一个对象,则访问x对象中函数成员a()的格式为()A.x.aB.x.a()C.x->aD.x->a()3.对象的四大基本特性是多态性、继承性、______和封装性。抽象性BB课程回顾624.为了使类中的成员不能被类外的函数通过成员操作符访问,则应把该成员的访问权限定义为______。private5.C++允许在结构中定义函数,这些函数称为()A.静态函数B.构造函数C.析构函数D.成员函数6.下列哪个不是面向对象的关键要素()A.抽象性 B.结构性C.封装性 D.多态性D.B.63真题7.C++类的构造函数名与______名称一样,且没有返回值。8.C++类中定义的成员默认访问属性为(

)A.public

B.privateC.protected

D.friend

类B9.不同对象调用同名函数,但导致完全不同行为的现象称为(

)A.抽象

B.封装

C.继承

D.多态性D6410.类的构造函数在以下什么情况下会被自动调用()A.定义成员函数时 B.定义对象时C.定义数据成员时 D.定义友元函数时11.与操作对象的数据类型相互独立的算法称为______.

泛型算法B6512.不同对象可以调用相同名称的函数,但可导致完全不同的行为的现象称为________。多态性13.在使用string类的find成员函数来检索主串中是否含有指定的子串时,若在主串中不含指定的子串,find函数的返回值是________。-166作业:编写程序完成字符串的替

温馨提示

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

评论

0/150

提交评论