面向对象程序设计(C++):第六章 数组、指针和字符串_第1页
面向对象程序设计(C++):第六章 数组、指针和字符串_第2页
面向对象程序设计(C++):第六章 数组、指针和字符串_第3页
面向对象程序设计(C++):第六章 数组、指针和字符串_第4页
面向对象程序设计(C++):第六章 数组、指针和字符串_第5页
已阅读5页,还剩67页未读 继续免费阅读

下载本文档

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

文档简介

第六章数组、指针与字符串本章主要内容数组指针动态存储分配(新)指针与数组指针与函数字符串1.概念数组是具有一定顺序关系的若干相同类型变量的集合体,组成数组的变量称为该数组的元素。数组属于构造类型。6.1数组2、一维数组的声明与引用一维数组的声明类型说明符数组名[常量表达式];

例如:inta[10];

表示a为整型数组,有10个元素:a[0]...a[9]6.1数组3、对象数组(1)声明类名数组名[元素个数];(2)访问方法通过下标访问数组名[下标].成员名6.1数组4、对象数组初始化(1)数组中每一个元素对象被创建时,系统都会调用类构造函数初始化该对象;(2)通过初始化列表赋值。例:

PointA[2]={Point(1,2),Point(3,4)};6.1数组假定一个类对象数组为A[n],当离开它定义的作用域时,系统自动调用该类析构函数的次数为()。0A1BnCn-1D提交单选题1分4、对象数组初始化(3)如果没有为数组元素指定显式初始值,数组元素便使用默认值初始化(调用默认构造函数)。6.1数组5、数组元素所属类的构造函数(1)不声明构造函数,则采用默认构造函数。(2)各元素对象的初值要求为相同的值时,可以声明具有默认形参值的构造函数。6.1数组5、数组元素所属类的构造函数(3)各元素对象的初值要求为不同的值时,需要声明带形参的构造函数。(4)当数组中每一个对象被删除时,系统都要调用一次析构函数。6.1数组例6-3对象数组应用举例//Point.h#if!defined(_POINT_H)#define_POINT_HclassPoint{public:Point();Point(intxx,intyy);~Point();voidMove(intx,inty);intGetX(){returnX;}intGetY(){returnY;}private:intX,Y;};#endif//6-2.cpp#include<iostream>usingnamespacestd;#include"Point.h"Point::Point(){X=Y=0;cout<<"DefaultConstructorcalled."<<endl;}Point::Point(intxx,intyy){X=xx;Y=yy;cout<<"Constructorcalled."<<endl;}Point::~Point(){cout<<"Destructorcalled."<<endl;}voidPoint::Move(intx,inty){X=x;Y=y;}12例6-3对象数组应用举例#include<iostream>#include"Point.h"usingnamespacestd;intmain(){cout<<"Enteringmain..."<<endl;PointA[2];for(inti=0;i<2;i++)A[i].Move(i+10,i+20);cout<<"Exitingmain..."<<endl;return0;}13例6-3对象数组应用举例运行结果:Enteringmain...DefaultConstructorcalled.DefaultConstructorcalled.Exitingmain...Destructorcalled.Destructorcalled.14例6-3对象数组应用举例1、内存地址(1)内存空间的访问方式通过变量名访问通过地址访问6.2指针1、内存地址(2)地址运算符:&例:intvar;则&var表示变量var在内存中的起始地址6.2指针2、指针变量的概念(1)概念指针:内存地址,用于间接访问内存单元指针变量:用于存放地址的变量6.2指针声明例:staticinti;staticint*i_pointer=&i;

指向整型变量的指针2、指针变量的概念6.2指针3、指针变量引用20003i_pointer*i_pointeri2000内存用户数据区变量i变量j变量

i_pointer362000200020043010int

i=3,int*i_pointer=&i;6.2指针4、指针变量的初始化(1)语法形式

[存储类型]数据类型*指针名=初始地址;例:int*pa=&a;6.2指针5、指针变量的赋值运算语法格式:指针变量=地址(1)指针变量赋的值是地址常量或变量,不能是普通整数。但可以赋值为整数0,表示空指针。(2)指针的类型是它所指向变量的类型,而不是指针变量本身数据值的类型,任何一个指针本身的数据值都是unsignedlongint型。6.2指针5、对象指针的一般概念(1)声明格式

类名*对象指针名;

例:PointA(5,10);Piont*ptr;ptr=&A;6.2指针5、对象指针的一般概念(2)通过指针对象访问对象成员格式:对象指针名->成员名ptr->getx()相当于(*ptr).getx();6.2指针假定AA为一个类,a为该类公有的数据成员,px为指向该类对象的一个指针,则访问px所指对象中数据成员a的格式为()。px(a)Apx[a]Bpx->aCpx.aD提交单选题1分假定AB为一个类,则执行“AB*s=newAB(a,5);”语句时得到的一个动态对象为()。sAs->aBs.aC*sD提交单选题1分假定AB为一个类,则执行“ABa,b(3),*p;”语句时共调用该类构造函数的次数为()。2A3B4C5D提交单选题1分对象指针应用举例intmain(){PointA(5,10);Point*ptr;ptr=&A; intx; x=ptr->GetX(); cout<<x<<endl;return0;}6.2指针曾经出现过的错误例子classFred; //前向引用声明classBarney{Fredx; //错误:类Fred的声明尚不完善

};classFred{Barneyy;};6.2指针正确的程序classFred; //前向引用声明classBarney{Fred*x; };classFred{Barneyy;};6、this指针当成员函数中的局部变量和类成员变量名称相同时,可以在成员函数内部采用this->变量形式使用同名的成员变量。6.2指针假定AA是一个类,abc是该类的一个成员函数,则参数表中隐含的第一个参数为()。abcA*thisBthisCthis&D提交单选题1分假定AA是一个类,“AA&abc();”是该类中一个成员函数的原型,若该函数存在对*this赋值的语句,当用x.abc()调用该成员函数后,x的值()。其中x是AA类的对象。已经被改变A可能被改变B不变C不受函数调用的影响D提交单选题1分7、指向类的非静态成员的指针(1)指向成员的指针只能访问类的公有成员(2)语法格式指向公有数据成员的指针类型说明符类名::*指针名;

指向公有函数成员的指针类型说明符(类名::*指针名)(参数表);6.2指针(3)指向类数据成员指针的赋值与使用赋值:指针名=&类名::数据成员名;使用:对象名.*类成员指针名;对象指针名—>*类成员指针名;7、指向类的非静态成员的指针6.2指针8、指向类的非静态成员的指针(4)指向类函数成员指针赋值及使用赋值:指针名=类名::函数成员名;使用:(对象名.*类成员指针名)(参数表)(对象指针名—>*类成员指针名)(参数表)6.2指针已知f1()是类A的公有成员函数,p是指向成员函数f1的指针,则对p进行赋值的下列方法中正确的是()p=f1;Ap=A::f1;Bp=&f1;CP=&A::f1;D提交单选题1分例6-13访问对象的公有成员函数的不同方式intmain() //主函数{ PointA(4,5); //声明对象A Point*p1=&A; //声明对象指针并初始化

//声明成员函数指针并初始化

int(Point::*p_GetX)()=Point::GetX; //(1)使用成员函数指针访问成员函数

cout<<(A.*p_GetX)()<<endl; //(2)使用对象指针访问成员函数

cout<<(p1->GetX)()<<endl; //(3)使用对象名访问成员函数

cout<<A.GetX()<<endl; }8、指向类的非静态成员的指针6.2指针9、指向类的静态成员的指针(1)指向类的静态数据成员语法格式:数据类型*指针;

指针=&类名::静态数据成员6.2指针9、指向类的静态成员的指针(2)指向类的静态函数成员语法格式:数据类型(*函数指针)(形参表);函数指针=类名::静态成员函数名;6.2指针例6-14通过指针访问类的静态数据成员#include<iostream>usingnamespacestd;classPoint //Point类声明{public: //外部接口

Point(intxx=0,intyy=0){X=xx;Y=yy;countP++;}//构造函数

Point(Point&p); //拷贝构造函数

intGetX(){returnX;} intGetY(){returnY;}

staticintcountP; //静态数据成员引用性说明private: //私有数据成员

intX,Y;};Point::Point(Point&p){ X=p.X;Y=p.Y;countP++;}intPoint::countP=0; //静态数据成员定义性说明intmain() //主函数{//声明一个int型指针,指向类的静态成员

int*count=&Point::countP; PointA(4,5); //声明对象A cout<<"PointA,"<<A.GetX()<<","<<A.GetY();//直接通过指针访问静态数据成员

cout<<"Objectid="<<*count<<endl; PointB(A); //声明对象B cout<<"PointB,"<<B.GetX()<<","<<B.GetY();//直接通过指针访问静态数据成员

cout<<"Objectid="<<*count<<endl; }41例6-14通过指针访问类的静态数据成员例6-15通过指针访问类的静态函数成员#include<iostream>usingnamespacestd;classPoint //Point类声明{public: //外部接口

//其它函数略

staticvoidGetC()//静态函数成员

{cout<<"Objectid="<<countP<<endl;}private: //私有数据成员

intX,Y; staticintcountP; //静态数据成员引用性说明};//函数实现略intPoint::countP=0; //静态数据成员定义性说明intmain() //主函数{//指向函数的指针,指向类的静态成员函数

void(*gc)()=Point::GetC; PointA(4,5); //声明对象A cout<<"PointA,"<<A.GetX()<<","<<A.GetY(); gc();//输出对象序号,通过指针访问静态函数成员

PointB(A); //声明对象B cout<<"PointB,"<<B.GetX()<<","<<B.GetY(); gc();//输出对象序号,通过指针访问静态函数成员}43例6-15通过指针访问类的静态函数成员1、动态申请内存操作符new(1)语法格式new类型名T(初值列表)(2)功能:在程序执行期间,申请用于存放T类型对象的内存空间,并依初值列表赋以初值。(3)结果值:成功:T类型的指针,指向新分配的内存。失败:0(NULL)

6.3动态存储分配假定AB为一个类,则执行“AB*px=newAB[n];”语句时将()。动态分配一个数组A动态分配一个对象B静态分配一个数组C静态分配一个对象D提交单选题1分假定AB为一个类,则执行“AB*px=newAB[n];”语句时调用该类无参构造函数的次数为()。nAn-1B1C0D提交单选题1分2、释放内存操作符delete(1)语法格式delete指针p(2)功能

释放指针p所指向的内存,p必须是new操作的返回值。

6.3动态存储分配设px是指向一个类对象的指针变量,则执行“deletepx;”语句时,将自动调用该类的()。无参构造函数A带参构造函数B析构函数C拷贝构造函数D提交单选题1分假定AB为一个类,px为指向该类的一个含有n个对象的动态数组的指针,则执行“delete[]px;”语句时共调用该类析构函数的次数为()。0A1BnCn+1D提交单选题1分例6-16动态创建对象举例#include<iostream>usingnamespacestd;classPoint{public:Point(){X=Y=0;cout<<"DefaultConstructorcalled.\n";}Point(intxx,intyy){X=xx;Y=yy;cout<<"Constructorcalled.\n";}~Point(){cout<<"Destructorcalled.\n";}intGetX(){returnX;}intGetY(){returnY;} voidMove(intx,inty) {X=x;Y=y;}private:intX,Y;};intmain(){cout<<"StepOne:"<<endl;Point*Ptr1=newPoint;deletePtr1;cout<<"StepTwo:"<<endl;Ptr1=newPoint(1,2);deletePtr1;return0;}运行结果:StepOne:DefaultConstructorcalled.Destructorcalled.StepTwo:Constructorcalled.Destructorcalled.51例6-16动态创建对象举例例6-17动态创建对象数组举例#include<iostream>usingnamespacestd;classPoint{//类的声明同例6-16,略};intmain(){Point*Ptr=newPoint[2];//创建对象数组

Ptr[0].Move(5,10);//通过指针访问数组元素的成员

Ptr[1].Move(15,20);//通过指针访问数组元素的成员

cout<<"Deleting..."<<endl;

delete[]Ptr;//删除整个对象数组

return0;}运行结果:DefaultConstructorcalled.DefaultConstructorcalled.Deleting...Destructorcalled.Destructorcalled.53例6-17动态创建对象数组举例例6-18动态数组类#include<iostream>usingnamespacestd;classPoint{//类的声明同例6-16…};classArrayOfPoints{public:ArrayOfPoints(intn){numberOfPoints=n;points=newPoint[n];}~ArrayOfPoints(){cout<<"Deleting..."<<endl;numberOfPoints=0;delete[]points;}

Point&Element(intn){returnpoints[n];}//返回第n+1个元素

private:Point*points;intnumberOfPoints;};54intmain(){ intnumber; cout<<"Pleaseenterthenumberofpoints:"; cin>>number;ArrayOfPointspoints(number);//创建对象数组//通过指针访问数组元素的成员

points.Element(0).Move(5,10);//通过指针访问数组元素的成员

points.Element(1).Move(15,20);}55例6-18动态数组类运行结果如下:Pleaseenterthenumberofpoints:2DefaultConstructorcalled.DefaultConstructorcalled.Deleting...Destructorcalled.Destructorcalled.56例6-18动态数组类3、动态创建多维数组(1)语法格式:new类型名T[下标表达式1][下标表达式2]…;(2)功能:如果内存申请成功,new运算返回一个指向新分配内存首地址的指针,是一个T类型的数组。例如:char(*fp)[3];fp=newchar[2][3];

6.3动态存储分配char(*fp)[3];fpfp+1fp[0][0]fp[0][1]fp[0][2]fp[1][0]fp[1][1]fp[1][2]58

6.3动态存储分配4、动态存储分配函数(4)void*malloc(size);参数size:欲分配的字节数返回值:成功,则返回void型指针;失败,则返回空指针。头文件:<cstdlib>和<cmalloc>

6.3动态存储分配5、动态内存释放函数(5)voidfree(void*memblock);参数memblock:指针,指向需释放的内存。返回值:无头文件:<cstdlib>和<cmalloc>

6.3动态存储分配6.4浅拷贝与深拷贝1、浅拷贝(1)发生场合当类有数据指针成员时,类对象之间进行直接赋值就会发生浅拷贝。(2)缺点:当被拷贝对象数据指针成员所指的内容发生改变,会影响到拷贝对象指针成员所指内容的值。注:默认拷贝构造函数在此场合都是浅拷贝。2、深拷贝(1)实现机制将目标拷贝对象数据成员指针分配新内存,然后将源拷贝对象数据成员指针所指的内容赋值给对应的目标拷贝对象数据成员指针所指内容。即拷贝和被拷贝对象数据成员指针指向不同的内存空间,两者之间互不影响。(2)实现深拷贝需要重写拷贝构造函数。6.4浅拷贝与深拷贝#include<iostream>usingnamespacestd;classPoint{//类的声明同例6-16//……};classArrayOfPoints{//类的声明同例6-18//……};6.4浅拷贝与深拷贝intmain(){ intnumber; cin>>number;ArrayOfPointspointsArray1(number);pointsArray1.Element(0).Move(5,10);pointsArray1.Element(1).Move(15,20);ArrayOfPointspointsArray2(pointsArray1);cout<<"CopyofpointsArray1:"<<endl;cout<<"Point_0ofarray2:"<<pointsArray2.Element(0).GetX()<<","<<pointsArray2.Element(0).GetY()<<endl;cout<<"Point_1ofarray2:"<<pointsArray2.Element(1).GetX()<<","<<pointsArray2.Element(1).GetY()<<endl;64例6-20对象的浅拷贝pointsArray1.Element(0).Move(25,30);pointsArray1.Element(1).Move(35,40);cout<<"AfterthemovingofpointsArray1:"<<endl;cout<<"Point_0ofarray2:"<<pointsArray2.Element(0).GetX()<<","<<pointsArray2.Element(0).GetY()<<endl;cout<<"Point_1ofarray2:"<<pointsArray2.Element(1).GetX()<<","<<pointsArray2.Element(1).GetY()<<endl;}65例6-20对象的浅拷贝运行结果如下:Pleaseenterthenumberofpoints:2DefaultConstructorcalled.DefaultConstructorcalled.CopyofpointsArray1:Point_0ofarray2:5,10Point_1ofarray2:15,20AfterthemovingofpointsArray1:Point_0ofarray2:25,30Point_1ofarray2:35,40Deleting...Destructorcalled.Destructorcalled.Deleting...66例6-20对象的浅拷贝拷贝前拷贝后pointsArray1的数组元素占用的内存pointsnumberOfPointspointsArray1pointsnumberOfPointspointsArray1pointsArray1的数组元素占用的内存pointsnumberOfPointspointsArray267例6-20对

温馨提示

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

评论

0/150

提交评论