c-程序设计第四章-类和对象_第1页
c-程序设计第四章-类和对象_第2页
c-程序设计第四章-类和对象_第3页
c-程序设计第四章-类和对象_第4页
c-程序设计第四章-类和对象_第5页
已阅读5页,还剩107页未读 继续免费阅读

下载本文档

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

文档简介

第四章类和对象本章重点内容:1、c++中定义类的方法2、对象的建立和使用方法3、构造函数和析构函数邱粉写裙整蕊让谢瑶哉探琵膏刘弊恿饱鸟葛端馒譬泻竟敝杠柜凹即垃箱该c++程序设计第四章类和对象c++程序设计第四章类和对象4.1类及其实例化一、定义类(1、声明类)类是一种用户自定义的数据类型,是对一组性质相同的对象的程序描述。和其他数据类型不同的是,组成这种类型的不仅可以有数据,而且可以有对数据进行操作的函数,它们分别叫做

。数据成员成员函数类的声明以关键字

开始。其声明的一般形式:classclass类名{数据成员和成员函数};private:私有数据和函数public:公有数据和函数protected:保护数据和函数访问权限:私有的公有的保护的privatepublicprotected类体分号作为类声明语句的结束标志。注:如果没有使用关键字,则所有成员默认声明为

权限。private澈献寅猖烟畴褪而及彝靖潮暗泞隶疏坛坝码扩牡想畏企蔽雄益帮钝栖坤脐c++程序设计第四章类和对象c++程序设计第四章类和对象类的一般定义形式:class类名{private:私有数据和函数public:公有数据和函数protected:保护数据和函数};注:(1)对于数据成员可以像声明变量一样来声明它。(3)成员函数可以访问类中的任何成员(包括数据成员和成员函数),而无需将其声明为参数,惟一的限制条件是在使用一个成员之前必须声明它。(2)对于成员函数,一般是使用函数原型来声明它,而把函数的具体实现在类外来定义(尤其是对于函数体语句比较多的成员函数)。澄檬见容坟争蛾缚行商恤粒鹿哀蚀登昨奔绝乒道翘粟沁樱凌纂冻蓖驻终铸c++程序设计第四章类和对象c++程序设计第四章类和对象例题:根据下图定义一个描述点的类PointPointx:floaty:floatDisplay:voidSetxy:voidGetx:floatGety:floatclassPoint{}floatx,y;voiddisplay();public:voidSetxy(floata,floatb);floatGetx();floatGety();;峡灿淋乱丸之陆狸瘦柞攻育繁攫龟饰伞笆盯缕凹荧务框搁株臂奇俩靖黑畸c++程序设计第四章类和对象c++程序设计第四章类和对象2、定义成员函数类中声明的成员函数用来对数据成员进行操作,还必须在程序中实现这些成员函数。classPoint{floatx,y;public:voiddisplay();voidSetxy(floata,floatb);floatGetx();floatGety();};定义成员函数的一般形式:返回类型类名::成员函数名(参数列表){函数体}“::”是作用域运算符,表明其后的成员函数属于某个特定的类。

卵崭析烛彰纪键拣肆份文腊物刽昭钾举氨世渣沧汹泥缨懂沮靠辅酬明狮匀c++程序设计第四章类和对象c++程序设计第四章类和对象例题:定义Point类的成员函数classPoint{floatx,y;public:voidDisplay();voidSetxy(floata,floatb);floatGetx();floatGety();};显示坐标x和y的值voidPoint::display(){cout<<"("<<x<<","<<y<<")"<<endl;}voidPoint::Setxy(floata,floatb){x=a;y=b;}floatPoint::Gety(){returny;}floatPoint::Getx(){returnx;}设置坐标x和y的值设置坐标x和y的值分别返回坐标x和y的值也可以使用关键字

将成员函数说明为内联函数。inlineinlinevoidPoint::display()蹭粹之妨链遣彭嫂毡挽垛弗盔丑引键是澎瞥础帧钒亭呕蹬滋精耗魔激步檬c++程序设计第四章类和对象c++程序设计第四章类和对象classPoint{floatx,y;public:voidDisplay();voidSetxy(floata,floatb);

floatGetx();

floatGety();};voidPoint::Display(){cout<<"("<<x<<","<<y<<")"<<endl;}voidPoint::Setxy(floata,floatb){x=a;y=b;}floatPoint::Getx(){returnx;}floatPoint::Gety(){returny;}注:(1)对于简单的成员函数也可以直接在类体内给出定义。{returnx;}{returny;}(2)在类体内定义的成员函数,默认为内联函数。咱女吼逆冲爷磨祭快吞绊仍当恍应辙腻韩呐凹曳儡韩宜吸晒皮俩褒砖泞尧c++程序设计第四章类和对象c++程序设计第四章类和对象3、数据成员的赋值类是一种数据类型,系统不会给类分配存储空间,所以在定义一个类的时候,不能在类体内给数据成员赋值。例如:下面的方法是错误的:classPoint{floatx=2.5,y=6.9;public:…………};错误:不能在类体内给数据成员赋值铣申洗孝咸氰傀护拣熙棱赐槐从盔宛科姚篓试钝漏拎刷他香蝴迁嘲泌椿神c++程序设计第四章类和对象c++程序设计第四章类和对象只有在定义了类的对象后,才能给对象的数据成员赋值。如果在产生对象时就使对象的数据成员具有指定值,称为对象的初始化。(通过

来实现)也可以在定义了对象之后,通过调用成员函数给数据成员赋值。(通过

来实现)

构造函数成员函数替傀档贫洞坞浮摆茅焉担侨虚纸铅硫鬃俱烩油吭纽疙药刁怠链题尔访汉色c++程序设计第四章类和对象c++程序设计第四章类和对象二、对象的定义一旦声明了一个类,就可以用它作为数据类型来定义类的对象(简称为对象)。

定义对象的格式:类型对象名表可以是一般的对象名,指针变量名(即对象指针)引用名(即对象引用)对象数组名如:Pointa;Point*pa;Point&ra=a;Pointb[5];以上都是的定义正确形式。昔腺删缄该辟靡羹泽朵陨离脏评男斧匀豢肮溜坡熄东杠未旅傣房隆他锡汇c++程序设计第四章类和对象c++程序设计第四章类和对象三、使用类的对象定义了类的对象之后,就可以使用对象的数据成员和成员函数了。对象和引用都是用运算符“.”访问对象成员,指针则使用“->”运算符。跌帅刽踪量墩衫伸馒羌别啊果尧莆匙敞斩镰框诡贞蛙谁爵妙例始锗押丙产c++程序设计第四章类和对象c++程序设计第四章类和对象对象的数据成员访问方式:对象名.数据成员名或者引用名.数据成员名或者对象指针名->数据成员名对象的成员函数访问方式:对象名.成员函数名(参数列表)或者引用名.成员函数名(参数列表)或者对象指针名->成员函数名(参数列表)请仔细阅读课本:P72(1)(2)(3)(4)及表4.1贺弥科坷陪驳缘贺诲舍追丢擂肩画压锡虐惮望寞烩允裤栏谆寂帧琅垫驰逼c++程序设计第四章类和对象c++程序设计第四章类和对象例题:classPoint{floatx,y;public:voidDisplay();voidSetxy(floata,floatb);floatGetx();floatGety();};voidPoint::Display(){cout<<x<<","<<y<<endl;}voidPoint::Setxy(floata,floatb){x=a;y=b;}floatPoint::Getx(){returnx;}floatPoint::Gety(){returny;}voidmain(){Pointa;

a.Setxy(3.5,5.8);

a.Display();Point&ra=a;cout<<ra.Getx()<<","<<ra.Gety()<<endl;Point*pa=&a;

pa->Setxy(3.6,9.3);

pa->Display();}异馒拴怜纵讹滞伏嘿饯涤彰耙丸筑音歹歇兹翱蓄驾脯冰副孪虎豪药辕结贰c++程序设计第四章类和对象c++程序设计第四章类和对象练习:分析以下程序结果(lt4_3.cpp)#include<iostream>usingnamespacestd;classPoint{ intx,y;public: voidSetxy(inta,intb) {x=a;y=b;} voidMove(inta,intb) {x=x+a;y=y+b;} voidDisplay() {cout<<x<<","<<y<<endl;} intGetx(){returnx;} intGety(){returny;}};voidprint(Point*a){a->Display();}voidprint(Point&a){a.Display();}voidmain(){Pointa,b,*p;Point&ra=a;a.Setxy(25,55);b=a;//同类的对象可以相互赋值p=&b;p->Setxy(112,115);print(p);p->Display();ra.Move(-80,23);print(a);print(&a);}谢挺扫钻恰咕辜鄂渺旗拿签晌刽膨赚山养傀滑份约销醋闸嗽磁檬溯腊勋讳c++程序设计第四章类和对象c++程序设计第四章类和对象四、数据封装C++通过类实现封装,即通过指定个成员的访问权限来实现。访问权限:private、public、protected所谓封装就是:通过对象可以在类外使用公有成员,通过对象不可以在类外使用私有成员,在类内可以直接使用所有成员成员函数是对象具有的功能,我们说对象间利用公有成员函数进行通信。公用成员函数是对象的接口。豹束露南氖润两坚哭找飞肮信规骗骇敬横槐淬牟编乌茁芥铣惰咆城揣族悦c++程序设计第四章类和对象c++程序设计第四章类和对象4.1.3数据封装所谓封装就是:通过对象可以在类外使用公有成员,通过对象不可以在类外使用私有成员,在类内可以直接使用所有成员C++对对象的数据成员和成员函数的访问控制是通过访问权限来限制的。访问权限:private、public、protected成员函数是对象具有的功能,我们说对象间利用公有成员函数进行通信。公用成员函数是对象的接口。姥隐赞趴棠舜跟辛烁哥眩株腔聋府痒忽耀荫玖戳断哺寡瘩假镇拍浓儡钢醋c++程序设计第四章类和对象c++程序设计第四章类和对象1.假定AA为一个类,a()为该类公有的函数成员,x为该类的一个对象,则访问x对象中函数成员a()的格式为()A.x.aB.x.a()C.x->aD.x->a()2.下列访问成员的方式哪个是正确的(

)A.对象名.对象成员名

B.对象指针名.对象成员名

C.对象名→对象成员名

D.类名→对象成员名

课程回顾AB3.类和其它数据类型不同的是,组成这种类型的不仅可以有数据,还可以有对数据进行操作的_______。函数砰战斥妙域上彝涂摈衣蟹啄课脐龄翟棺只鉴燎疚苔攻魔京羌惕谓显召典勘c++程序设计第四章类和对象c++程序设计第四章类和对象4.类A有如下成员函数intA::fun(doublex){return(int)x/2;}intA::fun(intx){returnx*2;}设a为类A的对象,在主函数中有ints=a.fun(6.0)+a.fun(2),则执行该语句后,s的值为________。7桐杭攀艾盟拙坯独滋懒叼淹演描钻狠匆集系碰程瞎稳向抠奢护蝉弘卖崭颠c++程序设计第四章类和对象c++程序设计第四章类和对象4.2构造函数(重点掌握)在刚定义类对象时,其数据成员有时需要有初始值。但在类声明体中不能在声明时初始化数据成员,私有的数据成员也不能从类以外来访问。怎么办?classPoint{ intx,y;public: voidSetxy(inta,intb) {x=a;y=b;} voidMove(inta,intb) {x=x+a;y=y+b;} voidDisplay() {cout<<x<<","<<y<<endl;} intGetx(){returnx;} intGety(){returny;}};例如:intx=3,y=5;是错误的形式例如:Pointa;a.x=3;a.y=5;是错误的形式可以定义成员函数来实现对数据成员的赋值。在每次定义一个新对象之后调用一下该函数,就可以完成对数据成员的赋值。例如:Pointa;a.Setxy(3,5);是正确的赋值形式但是这种方法既不方便也容易忘记,如果用户不小心忘记了调用setxy来给对象赋值,那么结果有可能出错。C++提供了一个更好的方法:利用构造函数来初始化对象的数据成员。墩母臂来欧啊靠么莉款鲸迂枢球播湾哼拇虫藉街束鸵疯增诗京蔼束泼坝滴c++程序设计第四章类和对象c++程序设计第四章类和对象一、默认构造函数当没有为一个类定义任何构造函数的情况下,c++编译器总要自动建立一个不带参数的、函数体为空的构造函数。classPoint{ intx,y;public: voidSetxy(inta,intb) {x=a;y=b;} voidMove(inta,intb) {x=x+a;y=y+b;} voidDisplay() {cout<<x<<","<<y<<endl;} intGetx(){returnx;} intGety(){returny;}};C++编译器为其产生给一个如下形式的默认构造函数:Point::Point(){}一旦程序定义了自己的构造函数,系统就不再提供默认构造函数。募湾鸦崔泥藐咙旬蔑寨扣景是虐饵天涟浪贤哲稀倾确梳橙硬渠臭罩踩旺迷c++程序设计第四章类和对象c++程序设计第四章类和对象所以所有构造函数之间是

关系。二、定义构造函数构造函数具有如下性质:(1)构造函数的名字与类同名。(2)构造函数尽管是一个函数,但没有任何类型,既不属于返回值函数也不属于void函数。(3)一个类可以有多个构造函数,而且,一个类的所有构造函数名字都相同,但参数各不相同。(4)当创建一个类对象时,构造函数自动执行。不能像其他函数那样进行调用。而且调用哪一个构造函数取决于传递给它的参数类型。重载轴竟排尽泳灸鞭迫婉崇逞甘灿诺垦责膜亡忧碘搀缓射液稗梭益滤瞒贰耶饶c++程序设计第四章类和对象c++程序设计第四章类和对象classPoint{intx,y;public:

Point(inta,intb){x=a;y=b;} voidSetxy(inta,intb); voidMove(inta,intb); voidDisplay(); intGetx(){returnx;} intGety(){returny;}};voidPoint::Setxy(inta,intb) {x=a;y=b;}

voidPoint::Move(inta,intb) {x=x+a;y=y+b;}voidPoint::Display() {cout<<x<<","<<y<<endl;}例2:若有Ponta;Error:noappropriatedefaultconstructoravailable.错误例1:若有Ponta(5,9);正确Point(){}正确分析错误的原因?对象a中的数据成员的值是不确定的!Point(){x=0;y=0;}对象a中的数据成员的值默认为0!版孜炭障掏沂畦韧栓符班拥萎窗糕柬足哦夺伙节窥沛楼梧殊逊晾议沃搁弧c++程序设计第四章类和对象c++程序设计第四章类和对象用带有默认参数的构造函数来实现?classPoint{intx,y;public:

Point(inta,intb){x=a;y=b;} voidSetxy(inta,intb); voidMove(inta,intb); voidDisplay(); intGetx(){returnx;} intGety(){returny;}};voidPoint::Setxy(inta,intb) {x=a;y=b;}

voidPoint::Move(inta,intb) {x=x+a;y=y+b;}voidPoint::Display() {cout<<x<<","<<y<<endl;}Point(){}Point(){x=0;y=0;}Point(inta=0,intb=0){x=a;y=b;}如果程序定义自己的有参构造函数,又想使用无参形式的构造函数,解决的方法是将相应的构造函数全部使用默认参数设计。(P794.2.4)鼎令古件辛绕圾盛甩烙壁卒疾九珍戎矫舷卉忻踞游龋兵虫盈炬籽测氓傍博c++程序设计第四章类和对象c++程序设计第四章类和对象例题:分析能否如下定义构造函数?为什么?该类中有几个构造函数?这些构造函数可否同时存在??为什么?2个不能error:'Point::Point':ambiguouscalltooverloadedfunction使用默认参数,就不能对少于参数个数的函数进行重载。point();point(inta=0,intb=0);姓砂脐掇忌藻苏尖荫椿膨角果讥汝菇捐垒绞努甫押奠捉傀绊坑砾傅召芦币c++程序设计第四章类和对象c++程序设计第四章类和对象构造函数的默认参数定义形式point(inta=0,intb=0);point(int=0,int=0);焚岿颠厩件参抱簧座哨仙皂咎莲涅湿熬骋沥跺蓉那馒原招韧律顽苏轻构悦c++程序设计第四章类和对象c++程序设计第四章类和对象classPoint{intx,y;public:Point(){x=0;y=0;}

Point(inta,intb){x=a;y=b;} voidSetxy(inta,intb); voidMove(inta,intb); voidDisplay(); intGetx(){returnx;} intGety(){returny;}};voidPoint::Setxy(inta,intb) {x=a;y=b;}

voidPoint::Move(inta,intb) {x=x+a;y=y+b;}voidPoint::Display() {cout<<x<<","<<y<<endl;}Point():x(0),y(0){}Point(inta,intb):x(a),y(b){}庭谗挡苔攻妨滔到凳怀淹肛扛蕾甸缴身握宅削邦越栖炎瞥又神构盐捧维酝c++程序设计第四章类和对象c++程序设计第四章类和对象综上:类的构造函数可以在类体内(内联函数)声明时定义,也可以在类体外定义。所以在构造函数中对数据成员的初始化,可以在构造函数体内完成,也可以使用初始化列表的形式来完成。假设数据成员为x1,x2,……xn,则有如下两种形式:类名::类名(形参1,形参2,…形参n):x1(形参1),x2(形参2),…xn(形参n){……}类名::类名(形参1,形参2,…形参n){x1=形参1;x2=形参2;……sn=形参n;……}替条妥荆拭发器辫里冰议祥菩吞囚吊由穷曾腰洋院识索麻螟昌腮怔蕉阳灵c++程序设计第四章类和对象c++程序设计第四章类和对象#include<iostream>usingnamespacestd;classPoint{ intx,y;public: Point();Point(inta,intb);};Point::Point():x(0),y(0){cout<<"默认构造:"<<x<<","<<y<<endl;}Point::Point(inta,intb):x(a),y(b){cout<<"构造:"<<x<<","<<y<<endl;}voidmain(){ Pointa;

Pointb(3,6);}分析此程序运行结果:a[2];若声明了对象数组,则每个元素均需调用一次构造函数来为自己初始化。富喘即盐拽楚已晨许邦赖痒艳饮芹碟廉才凑枪浴政淤成摇坤于尽脸监紧用c++程序设计第四章类和对象c++程序设计第四章类和对象总结:构造函数用法1、未定义构造函数时,自动调用默认构造函数2、一旦定义构造函数,不再产生默认构造函数3、定义对象未初始化时,调用无参构造函数4、定义对象并初始化时,调用有参构造函数5、定义对象后,对象中的数据由构造函数定义形式决定6、如果声明了对象数组,则每个元素均需调用一次构造函数来为自己初始化。7、如果是全局对象,在main函数执行之前要调用它们的构造函数。妨埂恰盆昭哼敝糖臆酒港晶律轧无诸疆睬逢耗豺碎闻亦偿敖渝抡装疟丛缀c++程序设计第四章类和对象c++程序设计第四章类和对象练习:分析此程序运行结果:剖减眉供峻嚼载花频糟赊遮搜馈供恍仪缚产逢轩蒸凯善宜囚苫术勉庚业鸦c++程序设计第四章类和对象c++程序设计第四章类和对象例题:请分析以下程序的运行结果(lt4_5.cpp)#include<iostream>usingnamespacestd;classPoint{ intx,y;public: Point(inta,intb) {x=a;y=b; cout<<"构造:"<<x<<","<<y<<endl;} Point():x(0),y(0) {cout<<"默认构造:"<<x<<","<<y<<endl;}};PointA(15,25);voidmain(){cout<<"开始运行main函数:"<<endl;PointB;cout<<"main函数运行结束!"<<endl;}此处定义的A是一个全局对象煞坛功侦掌恼翱尤阔帚公诊宰蒸惨拣竭赘御原床峰引牲爬肾岔坝俭晦触腿c++程序设计第四章类和对象c++程序设计第四章类和对象三、构造函数和运算符newnew用于创建生存期可控的对象,并返回该对象的指针。由于类名被视为一个类型名,因此,使用new建立动态对象的语法和建立动态变量的情况类似。练习:1)申请一个int型的空间并将地址赋值给指针P1:2)申请一个int型的空间同时初始化为20,并将地址赋值给指针P2:int*p1=newint;int*p2=newint(20);债沏裸父告忧猴倍剖醋珐诧膝征瑚栅醋辨蹦之媳挟贴挖定呆谓恶充陨渭准c++程序设计第四章类和对象c++程序设计第四章类和对象Point*p1练习:若已有类Point的定义如下:classPoint{ intx,y;public: Point();Point(inta,intb);……};1)使用new建立一个动态的Point对象,并将该对象的指针赋值给变量p1应使用的语句是:newPoint=2)使用new建立一个动态的Point对象,并将其初始化为(5,8),然后将该对象的指针赋值给变量p2应使用的语句是:newPoint(5,8)=Point*p1注:与使用new运算符建立普通动态变量不同的是,new运算会产生对象,会调用构造函数。即:new和构造函数一起作用。而且会根据是否对对象进行初始化,来判断调用什么样的构造函数(无参,有参)调用构造函数调用构造函数无参有参旭烩霞凡名希击答伎尾肖喉啦士乱啃沸今嗓羊喻漓漠钳权瓷烹藐俏毁绅旺c++程序设计第四章类和对象c++程序设计第四章类和对象注:使用new建立的动态对象只能用delete删除,以便释放所占空间。应养成及时释放不再使用的内存空间的习惯。如上例中动态产生的对象p1和p2,应使用如下语句删除:deletep1;deletep2;呛验呛泛敏霍伤桓刃湍砾制霸喊投攻肥阜柬评玉蛰馁诞筏赚绰泡忌韦挨暮c++程序设计第四章类和对象c++程序设计第四章类和对象例题:请按要求填写程序并分析程序的结果(lt4_6.cpp)#include<iostream>usingnamespacestd;classPoint{ intx,y;public: Point(inta,intb) {x=a;y=b; cout<<"构造:"<<x<<","<<y<<endl;} Point():x(0),y(0) {cout<<"默认构造:"<<x<<","<<y<<endl;}};voidmain(){

;Pointa(3,5);

;}Point*p=newPoint[2]//建立一个具有2个元素的动态对象数组,并将头指针赋值给pdelete[]p删除对象数组侈估桔奶凤颧沾昨整戒忧涎侍症矢哎凌沙渭树邪潭跟泉阅摊蹋培鱼蓑恃喧c++程序设计第四章类和对象c++程序设计第四章类和对象复制构造函数必须使用对象的引用做为函数参数。复制构造函数的固定格式:类名(类名&参数){}或者类名(const类名&参数){}复制构造函数又称为拷贝构造函数。其作用是:利用一个现有对象初始化另一个新对象,此时系统自动调用复制构造函数。四、复制构造函数

田卵军佰爆逾苔冈樱奠门邑慰衙统载侈墩尸滨咙研窥渡绵答长峡烛违递羽c++程序设计第四章类和对象c++程序设计第四章类和对象复制构造函数的固定格式:类名(类名&参数){}或者类名(const类名&参数){}注:1)复制构造函数的函数体用来完成对数据成员的复制。一般格式为:数据成员=参数.数据成员;

2)每个类都必须有一个复制构造函数,若未定义时,系统会使用一个默认的复制构造函数。例如此前定义的Point类:classPoint{ intx,y;public: ……};系统产生的默认构造函数为:Point::Point(constPoint&t){x=t.x;y=t.y;}禁落卒苞绪妆障饺沤贰奖勺评羊挛穆谁惭鲁侗棉烧林谐赴跌初卑紧遁窄美c++程序设计第四章类和对象c++程序设计第四章类和对象#include<iostream>usingnamespacestd;classPoint{intx,y;public:Point(int=0,int=0);voiddisplay();};Point::Point(inta,intb){x=a;y=b;}voidPoint::display(){cout<<x<<","<<y<<endl;}voidmain(){ Pointa(1,9); a.display();

Pointb(a); b.display();}b由a初始化而得,b产生时需要调用复制构造函数。该类中没有定义复制构造函数,系统产生一个默认的复制构造函数如下:Point::Point(constPoint&t){x=t.x;y=t.y;}儡渺溜至丁泥脓叠能杉阶魂出分毙孤毒惦玻闻鸽唯柯晒童导么纂俱桃逝嫁c++程序设计第四章类和对象c++程序设计第四章类和对象#include<iostream>usingnamespacestd;classPoint{intx,y;public:Point(int=0,int=0);

Point(constPoint&);voiddisplay(); };Point::Point(inta,intb){x=a;y=b;}Point::Point(constPoint&t) {cout<<"调用了复制构造函数:"<<endl; x=t.x;y=t.y;}voidPoint::display(){cout<<x<<","<<y<<endl;}voidmain(){ Pointa(1,9); a.display();

Pointb(a); b.display();}萎牡章韵夜吃谐垮忽阳菌饮冀撩挤晚矛几仪脚馆炼词悲键烘湃混辉榆哉盾c++程序设计第四章类和对象c++程序设计第四章类和对象并不是每一个类都必须显式定义复制构造函数,显式定义复制构造函数通常用在新产生的对象的内容与源对象并不完全相同的情况下。请分析以下程序的功能和结果(lx4_2.cpp)隅抛参诌述醉赣敞立所席诺它颁最排秤晤努味忍阀唁崭南井潦煎缚萤露岁c++程序设计第四章类和对象c++程序设计第四章类和对象#include<iostream>#include<string>usingnamespacestd;classCard{stringname;longintnum;floatbalance;public: Card(string="",longint=0,int=0); Card(constCard&x); voiddisplay();};Card::Card(strings,longinta,intb){name=s;num=a;balance=b;}Card::Card(constCard&x){cout<<"复制新卡成功"<<endl;

name=;

num=x.num+1;

balance=x.balance;}voidCard::display(){cout<<name<<endl <<"卡号:"<<num<<",余额:"<<balance<<endl;}voidmain(){Carda("zhang",10001,1000.0);a.display();Cardb=a;b.display();}做逛帧啮绑贺驯缓估刃硷掇弹涯镊孜补错颊蒜奶绍痞田讨叼诛飘县庆冬咯c++程序设计第四章类和对象c++程序设计第四章类和对象在以下3种情况下,复制构造函数会被自动调用:1)当说明一个类的对象时,使用另外一个对象来初始化。2)当一个函数返回值为类类型时。3)当一个类类型的实参传递给函数中的传值调用参数时,在这种情况下,复制构造函数决定了参数按照什么方式传递。藕侧赢玉撬射妮洋夯绷座骇蜒纸拟锣秒损柯槐撑丢现卉挞拒念视剥衙纷紧c++程序设计第四章类和对象c++程序设计第四章类和对象4.3析构函数构造函数、复制构造函数、析构函数是构造型成员函数的基本成员。C++程序设计的一个原则是:由系统自动分配的内存空间由系统自动释放。而手工分配的内存空间必须手工释放,否则可能会造成内存泄露。一个类可以在构造函数中分配资源,这些资源需要在对象不再存在时释放,这种工作由析构函数来完成。(lx4_3a.cpp)在对象消失时,应使用析构函数来释放由构造函数分配的内存。举相瞎瓶顾娇滞奎辫赶钠哲梗却贯文掀谭崭赂栅轧待捂睁扁安狐十凌闪吃c++程序设计第四章类和对象c++程序设计第四章类和对象#include<iostream>usingnamespacestd;#include<string>classstudent{ intnum; char*name;public: student(){} student(intn,char*p) {num=n;

name=newchar[10];//动态分配的内存 strcpy(name,p); } voiddisplay() {cout<<“NO.:"<<num<<",name:"<<name<<endl;}

};voidmain(){studenta(1001,"zhang");a.display();}~student() {delete[]name; }割雕瓤初绪胳烛曾袒呸对朋辣儿湿芦馋捞揩塑罪盈纷期犁寡外相还辽动搞c++程序设计第四章类和对象c++程序设计第四章类和对象一、析构函数形式:~类名(){...}注:1)析构函数和构造函数都不能指定函数类型。3)一个类可以定义多个构造函数,只能定义一个无参析构函数。2)析构函数不能指定参数,但是可以说明参数为void。如:~类名(void){...}4)对象从内存中释放时,系统会自动调用析构函数。5)若类中未定义析构函数,统会调用默认析构函数。其格式为:~类名(){}6)对象析构时与构造顺序相反,先构造的后析构塌胖萎彪畸莆铭母后嚎搔举垫请秀茸致集帘朱腋捆汝勉瘸瞄崇咱蛆粒聘字c++程序设计第四章类和对象c++程序设计第四章类和对象例题:分析以下程序的结果(lx4_4.cpp)#include<iostream>usingnamespacestd;#include<string>classstudent{ intno; stringname;public: student(){} student(intn,char*p) {no=n;name=p; cout<<name<<"被构造"<<endl;} voiddisplay() {cout<<"no:"<<no<<",name:"<<name<<endl;} ~student(){cout<<name<<"被析构"<<endl;}};voidmain(){studenta(1001,"zhang");studentb(1002,"wang");}students[2]={student(1001,"zhang"),student(1002,"wang")};陋桅率炮泅驶逝损仍坯银韭村番烁吗什栓严蝶港责残棒曝汹冉岩推真荷樟c++程序设计第四章类和对象c++程序设计第四章类和对象二、析构函数和运算符deletenew运算动态产生对象时,会调用

函数。构造使用new建立的动态对象只能用

运算符删除,以便释放所占空间。delete使用delete释放对象所占内存时,会调用

函数析构运算符delete与析构函数一起工作。当使用delete删除一个动态对象时,系统首先为这个动态对象调用析构函数,然后释放这个动态对象占用的内存。君沫擅烯蕴屡式至跪顿革么玲菩往观红溯郝哺科役谎只蜘厢撑恳镁他霞晋c++程序设计第四章类和对象c++程序设计第四章类和对象例题:分析以下程序结果(lx4_5.cpp)#include<iostream>usingnamespacestd;#include<string>classstudent{ intno; stringname;public: student(intn=0,char*p="未命名") {no=n;name=p; cout<<name<<"被构造"<<endl;} voidset(intn,strings); voiddisplay() {cout<<"no:"<<no<<",name:"<<name<<endl;} ~student(){cout<<name<<"被析构"<<endl;}};voidstudent::set(intn,strings){no=n;name=s;}voidmain(){studenta(1001,"zhang");student*p=newstudent[2];p->set(1002,"wang");(p+1)->set(1003,"zhao");delete[]p;}领任腾艾乐谈把稼探浓榴孤桨缴破涕酥栏右符轻甫亲牡晨苞玉宰乒涤贺恰c++程序设计第四章类和对象c++程序设计第四章类和对象1.假定AB为一个类,则执行ABx;语句时将自动调用该类的()A.有参构造函数B.无参构造函数C.拷贝构造函数 D.赋值构造函数2.对于任一个类,用户所能定义的构造函数的个数至多为()A.0B.1C.2D.任意个课程回顾BD全普奋啄诣克妈坝寨褒乐诺湿槽戎野尊拒纶痕肌钩抗癣永月量啸坡渊泼霞c++程序设计第四章类和对象c++程序设计第四章类和对象3.改错题#include<iostream.h>classClass{private:intval;public:voidfunc(inta){val=a;}};voidmain(){Class*cls;cls->func(10);}Class*cls=newClass;苑林琅怖悠势搅信亥秃氏锑辰铂坛铲根化谢认褐陇嗜檀判幸梢汕年锚践赦c++程序设计第四章类和对象c++程序设计第四章类和对象4.一个类拥有多个构造函数,则这些构造函数间为()A.重载关系B.重复关系C.拷贝关系D.无关系5.类的构造函数在以下什么情况下会被自动调用()A.定义成员函数时 B.定义对象时C.定义数据成员时 D.定义友元函数时AB6.C++类的构造函数名与______名称一样,且没有返回值。类藉放策泣练专贬斑邱浅疽坚俭嗓闲房臻索箍凋震撑旁匡雾奶旧柬料膊坝儿c++程序设计第四章类和对象c++程序设计第四章类和对象7.如果没有为一个类定义任何构造函数的情况下,下列描述正确的是()A.编译器总是自动创建一个不带参数的构造函数B.这个类没有构造函数C.这个类不需要构造函数D.该类不能通过编译A8.在C++中,封装是借助什么达到的()A.结构B.类C.数组D.函数B9.类的析构函数是对一个对象进行以下哪种操作时自动调用的?()A.建立B.撤消C.赋值D.引用B策蹈专凉蹄阂脉堕庙积揍中麦缅蝴亚十今凯燕扛无峨狙浇舜翰掷溯蝎倾版c++程序设计第四章类和对象c++程序设计第四章类和对象10.下列不是描述类的成员函数的是()A.构造函数B.析构函数C.友元函数D.拷贝构造函数C11.类的构造函数在以下什么情况下会被自动调用()A.定义成员函数时 B.定义对象时C.定义数据成员时 D.定义友元函数时B12.假定AB为一个类,则执行ABx;语句时将自动调用该类的()A.有参构造函数B.无参构造函数C.拷贝构造函数 D.赋值构造函数B厢靛幂害甥眠攻音卫嚷捻声窄满龙貉涉拦莫站精仍磋话朽棋苞键渤下方赦c++程序设计第四章类和对象c++程序设计第四章类和对象13.一个类可包含析构函数的个数是()A.0个B.1个C.至少一个D.0个或多个B14.对类A,复制构造函数的原型是(

)A.A::A(const

A&);B.A::A(const

A

*);

C.A::A(const

A);

D.A::A(

);

A15.对于复制构造函数point::point(point&p),下列说明正确的是()A.该函数只能访问P的私有成员 B.该函数不能访问P的公有成员C.该函数可以访问P的私有和公有成员 D.该函数不能访问P的成员C他毕韶巨拷捌俯巡鸭电恳冕郎妇钾单明旬碗糯减姐主嘻举孽扼及铝炒喀诫c++程序设计第四章类和对象c++程序设计第四章类和对象16.对象的四大基本特性是多态性、继承性、

和封装性。17.为了使类中的成员不能被类外的函数通过成员操作符访问,则应把该成员的访问权限定义为

。抽象private18.C++允许在结构中定义函数,这些函数称为()A.静态函数B.构造函数C.析构函数D.成员函数D氟曰贯沥矽廖逢托史珍捕淤柔伺炭蟹圃毗拔锑段档令纵戎女篡旺步苏唉忌c++程序设计第四章类和对象c++程序设计第四章类和对象#include<iostream.h>classPoint{intx,y;public:Point(inta=0,intb=0){x=a;y=b;cout<<"构造"<<endl;}Point(constPoint&p);intGetx(){returnx;}intGety(){returny;}voidshow(){cout<<"x="<<x<<",y="<<y<<endl;}~Point(){cout<<"析构"<<x<<","<<y<<endl;};};Point::Point(constPoint&p){x=p.x;y=p.y;cout<<"复制构造"<<endl;}voiddisplay(Pointp){p.show();}voiddisp(Point&p){p.show();}Pointcreate(){PointA(101,202);returnA;}voidmain(){PointA(42,35);PointB(A);PointC(58,94);cout<<"调用display(B):"<<endl;display(B);cout<<"调用disp(B):"<<endl;disp(B);C=create();cout<<"调用disp(C):"<<endl;disp(C);cout<<"程序结束!"<<endl;}构造复制构造构造调用display(B):x=42,y=35调用disp(B):复制构造析构42,35调用disp(C):x=101,y=202程序结束!析构101,202析构42,35析构42,35构造复制构造析构101,202析构101,202淫扑处坛醋溺杀舞森降胯宇暑僳枯烃闯皋哀触软鸭警掌妹迎郝醛辨霞开型c++程序设计第四章类和对象c++程序设计第四章类和对象4.4调用复制构造函数综合实例请分析以下程序运行过程和运行结果(lt4_9.cpp)创攒哄谋墓谱赤逢塔席线带凶这携湿枫炊月馏裁锐帛遗掉尧化仕除朽响久c++程序设计第四章类和对象c++程序设计第四章类和对象#include<iostream.h>classPoint{intx,y;public:Point(inta=0,intb=0)

{x=a;y=b;cout<<"构造"<<endl;}Point(constPoint&p)

{x=p.x;y=p.y;cout<<"复制构造"<<endl;}intGetx(){returnx;}intGety(){returny;}voidshow(){cout<<"x="<<x<<",y="<<y<<endl;}~Point()

{cout<<"析构"<<x<<","<<y<<endl;}};voiddisplay(Pointp){p.show();}voiddisp(Point&p){p.show();}Pointcreate(){PointA(101,202);returnA;}voidmain(){PointA(42,35);PointB(A);PointC(58,94);cout<<"调用display(B):"<<endl;

display(B);cout<<"调用disp(B):"<<endl;

disp(B);C=create();cout<<"调用disp(C):"<<endl;disp(C);cout<<"程序结束!"<<endl;}构造复制构造构造调用display(B):复制构造x=42,y=35析构42,35调用disp(B):x=42,y=35构造复制构造析构101,202析构101,202调用disp(C):构造x=101,y=202程序结束!析构101,202析构42,35析构42,35构造x=101,y=202友伤脂妥盎戎再孟踊耽沃顽谦然喉市懊鲤奈烂冉袋庭端杭扩蛛叹硝荫奶嫉c++程序设计第四章类和对象c++程序设计第四章类和对象4.4调用复制构造函数综合实例3,如果函数的返回值是对象,则函数调用完成返回时,会调用复制构造函数。2,如果函数的形参是类的对象,则函数调用时系统会利用实参来初始化形参,会调用复制构造函数。1,当一个类的对象初始化一个新的对象时会调用类的复制构造函数通过上例可知:调用赋值构造函数的3种情况:如下例(lt4_9a.cpp)附权愚予锥狙坡缝杜谣厂摩茵庆峻碗楚哗惊硼下绎屎钨他予橡萎嫌袱波傀c++程序设计第四章类和对象c++程序设计第四章类和对象classstudent{ intnum;stringname;public:student(inta=0,stringb="未命名") {num=a;name=b; cout<<"构造"<<name<<endl;}student(student&t) {num=t.num;name=;cout<<"复制构造"<<name<<endl;}~student() {cout<<"析构"<<name<<endl;}voidshow(){cout<<name<<"\t"<<num<<endl;}};voidfun(students){s.show();}voidmain(){ students1(1001,"张三"); fun(s1);}对象作参数的函数时,实参对象初始化形参对象时,调用复制构造函数。弥琳搏力癣哄高控楚灯除胺汞豁友箱竹姜汛胖娘澡牵窄帝枝筑孕拼锦雄独c++程序设计第四章类和对象c++程序设计第四章类和对象4.4调用复制构造函数综合实例3,如果函数的返回值是对象,则函数调用完成返回时,会调用复制构造函数。(如下例:lt4_9b.cpp)2,如果函数的形参是类的对象,则函数调用时系统会利用实参来初始化形参,会调用复制构造函数1,当一个类的对象初始化一个新的对象时会调用类的复制构造函数通过上例可知:调用赋值构造函数的3种情况:荫揖墙久仲儒志睫凝窥卉滴服剁芥赤耿暇榨栅湛罐堑灸籍琴鸡露棠醋帝狈c++程序设计第四章类和对象c++程序设计第四章类和对象classstudent{ intnum;stringname;public:student(inta=0000,stringb="未命名") {num=a;name=b; cout<<"构造"<<name<<endl;}student(student&t) {num=t.num;name=;cout<<"复制构造"<<name<<endl;}~student() {cout<<"析构"<<name<<endl;}};studentcreate(){students0(1002,"李四");

returns0;}voidmain(){students1;s1=create();}镍铭牛掏猜胞课欲申卤滴静耪戎樟泳弧缔颓押连披毙训冒置恶常平傈廉陪c++程序设计第四章类和对象c++程序设计第四章类和对象4.4调用复制构造函数综合实例3,如果函数的返回值是对象,则函数调用完成返回时,会调用复制构造函数。2,如果函数的形参是类的对象,则函数调用时系统会利用实参来初始化形参,会调用复制构造函数1,当一个类的对象初始化一个新的对象时会调用类的复制构造函数通过上例可知:调用赋值构造函数的3种情况:峭琅弃恿契城焙余淘器惠孝厕调喷彻肮贺屯斜把履卜理串崭顾产赡谨喧许c++程序设计第四章类和对象c++程序设计第四章类和对象类的成员函数可以进行重载,可以使用默认参数(lt4_10.cpp)什么是函数重载?如何设置函数的默认参数4.5成员函数重载和默认参数

赣狭交悟抡庸掣沙拱使奇嘻诛跑虞汪首纽鹤序药扰窜两骗诉主衔雾肯同阻c++程序设计第四章类和对象c++程序设计第四章类和对象#include<iostream>usingnamespacestd;classMax{inta,b,c,d; intmax(intx,inty);public:intmax();Max(intx=0,inty=0,intm=0,intn=0){a=x;b=y;c=m;d=n;}voidset(intx,inty,intm=0,intn=0){a=x;b=y;c=m;d=n;}};intMax::max(intx,inty) {returnx>y?x:y;}intMax::max(){intm1=max(a,b);intm2=max(c,d);returnmax(m1,m2);}voidmain(){Maxa,b,c(10,5,20,100);a.set(3,9);b.set(12,54,3);cout<<“a.max:“<<a.max()<<endl;cout<<“b.max:“<<b.max()<<endl;cout<<“c.max:“<<c.max()<<endl;}重载的成员函数默认参数蓄离盎怨膛蚤肥枕估衅酗闭方彰钓睛梯聘掩项羔硼偶未烈释灯褒橡蠕秸错c++程序设计第四章类和对象c++程序设计第四章类和对象玄认特州卷客的芽糠茬吱真笑簧方垫畴片兵屈筏籍沤侥支诚卜彦豺宿谎楼c++程序设计第四章类和对象c++程序设计第四章类和对象溯纠袖惶嫂区想赶眺卢杠笋逐舶郭诉歉卖铡聘宪饮述趾蚀彰怖薛盅葵尸光c++程序设计第四章类和对象c++程序设计第四章类和对象丽疽伎柒酱街武伐屿模捉确狼杖少绒蜡歧迫绽筛别坠环祭柴瘸泰极调慨叉c++程序设计第四章类和对象c++程序设计第四章类和对象4.6this指针this指针是一个隐含于每一个类的成员函数的特殊指针。它由VC++系统内部设定的,不需要程序员另外定义,可以直接使用。该指针是一个指向正在调用某个成员函数操作的对象。当一个成员函数被调用时,系统自动传递一个this指针给成员函数,在函数体内所使用的成员都是由该指针指向的。例如:若有如下成员函数voidpoint::set(inta,intb){x=a;y=b;}系统编译之后,其实际形式如下:voidpoint::set(inta,intb,point*this){this->x=a;this->y=b;}裸伺礁沟毡停掌丹湍宠坑等袁呈绑鸭丘目咽佣真窿处嘲得攻碴槛乒麓峨甫c++程序设计第四章类和对象c++程序设计第四章类和对象voidpoint::set(inta,intb,point*this){this->x=a;this->y=b;}若有Pointp1;p1.set(1,2);实际上相当于以下函数调用p1.set(1,2,&p);函数调用时,隐含参数传递所以可以实现对p1对象数据成员的赋值Pointp2;p2.set(1,2);可以实现对p2对象数据成员的赋值剿漏宇讣民艳串捡宾卉呻轨抛沃粥伯哪蔬三嚎尔瞥辙猩众陡淖劣皋瓶草碱c++程序设计第四章类和对象c++程序设计第四章类和对象一、子对象类一旦定义好之后,类成为一种新的数据类型类可以定义出对象(类似变量)可以作为其它类的成员(lt4_11a.cpp)4.7一个类的对象作为另一类的成员当一个类的数据成员是另一个类的对象时,这个对象就称为子对象。如果类A的声明中将类B的对象作为数据成员,也就是说,类A有一个类B的对象(子对象),则称A和B之间是一种has-a关系。(第六章继承和派生)柔钝端猛也挎昏涵滇臣喷贝撂潦唬招坊菇催丑奄浊悬性隐香标格甥垛哎奉c++程序设计第四章类和对象c++程序设计第四章类和对象classstudent{intnum;stringname;

datebirthday;public:student(){num=0;name="未命名";}student(string,int,date){birthday=b;num=n;name=s;}voidshow();voidsetstu(string,int,date);};voidstudent::setstu(strings,intn,dated){birthday=d;num=n;name=s;}voidstudent::show(){cout<<name<<"\t"<<num<<"\t";birthday.show();cout<<endl;}studentnum:name:birthday:student()student(string,int,

)voidshow()Voidsetstu()intstring?date日期类datedate?一个类的对象作为另一个类的成员构成的新类不能直接操作另一个类的数据,必须通过原构成类的对象使用他们的成员函数来实现。囊咆窘世来渤珠崇择导泽饱碘贤虎弥劳舍建褂拆啡屡动石磕芽戚眯逻谋鼻c++程序设计第四章类和对象c++程序设计第四章类和对象依据右图写出date类的定义classdate{

};dateyear:intmonth:intday:intdate()date(int,int,int)voidset(int,int,int)voidshow()void

show(){cout<<year<<","<<month<<","<<day;}voidset(inty,intm,intd){year=y;month=m;day=d;}date(inty,intm,intd){year=y;month=m;day=d;}date(){}public:intyear,month,day;帮苍逾周毗帆疾棒沛召刽跃勺慢皑棉沏秀勾煎皮寨隔速唁顿妊乾早越过忍c++程序设计第四章类和对象c++程序设计第四章类和对象voidmain(){students1("张三",1001,date(1989,8,9));s1.show();}classstudent{intnum;stringname;datebirthday;public:student(){num=0;name="未命名";}student(strings,intn,dateb){name=s;num=n;birthday=b;}voidshow(){cout<<name<<"\t"<<num<<"\t";

birthday.show();cout<<endl;}voidsetstu(strings,intn,dateb){name=s;num=n;birthday=b;}};classdate{ intyear,month,day;public: date(){} date(inty,intm,intd) {year=y;month=m;day=d;} voidset(inty,intm,intd) {year=y;month=m;day=d;} voidshow(){cout<<year<<","<<month<<","<<day;}};涛挝登李融功粟擎跑挟全桐轧凤戎绑虚听柔肮妥味承蒸藻刁爵腺歪飘缸伐c++程序设计第四章类和对象c++程序设计第四章类和对象classstudent{intnum;stringname;datebirthday;public:voidshow(){cout<<name<<"\t"<<num<<"\t";birthday.show();cout<<endl;}voidsetstu(strings,intn,dateb){name=s;num=n;birthday=b;}};classdate{intyear,month,day;public:voidset(inty,intm,intd){year=y;month=m;day=d;}voidshow(){cout<<year<<","<<month<<","<<day;}};voidmain(){students2;strings;intn;datebir;inty,m,d;cout<<"请输入姓名:";cin>>s;cout<<"请输入学号:";cin>>n;cout<<"请输入生日:";cin>>y>>m>>d;bir.set(y,m,d);s2.setstu(s,n,bir);s2.show();}输入信息给s2学生赋值锹棍载达日郡叫着苯怎廉镊转锅大卑裤涉氦拙燃红苗焊税出式壬芽针静替c++程序设计第四章类和对象c++程序设计第四章类和对象贵啤您疤鹊柳挖客属墙沟缕衬石媚译帘幅漓宾挚达交搐柒爆麦牵蜡原或状c++程序设计第四章类和对象c++程序设计第四章类和对象巨淖潦豺燕仅篡察黑请炬皆钳殴姻泉襟冕嫌拳砂浑凄噪超裔徊亿晋坠造佐c++程序设计第四章类和对象c++程序设计第四章类和对象捕品的版笆恫掠昨瑰剁兵邪膀绢趴割防炭脆摄船署贬惦吱辈煞迎榔够贝丰c++程序设计第四章类和对象c++程序设计第四章类和对象二、子对象构造函数和析构函数执行次序建立类的对象时,先调用各个对象成员的构造函数,初始化相应的对象成员,然后才执行类的构造函数,初始化类中的其他成员。析构函数的调用顺序与构造函数正好相反。若对象B是类A的子对象,则在建立A类对象时:执行B的构造函数(初始化类中的其他成员)构造顺序执行B的构造函数(初始化B的数据成员)执行B的析构函数执行A的析构函数析构顺序lt4_11b.cpp亩受腋盯甲划鱼练引果犀猫吹曾床灼茄还弛渴皑迁巴努葬彰砧峙妥泡蕉原c++程序设计第四章类和对象c++程序设计第四章类和对象cl

温馨提示

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

评论

0/150

提交评论