C面向对象程序设计.pptx

上传人:莉*** 文档编号:87173537 上传时间:2023-04-16 格式:PPTX 页数:98 大小:374.88KB
返回 下载 相关 举报
C面向对象程序设计.pptx_第1页
第1页 / 共98页
C面向对象程序设计.pptx_第2页
第2页 / 共98页
点击查看更多>>
资源描述

《C面向对象程序设计.pptx》由会员分享,可在线阅读,更多相关《C面向对象程序设计.pptx(98页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、2.1.1 类的定义定义类时还应注意:(1)类中的数据成员的数据类型可以是任意的,但不允许对所定义的数据成员进行初始化,例如类CMeter中,下面的定义是错误的:classCMeter.private:intm_nPos=10;/错误.;(2)在“public:”或“private:”后面定义的所有成员都是公有或私有的,直到下一个“public:”或“private:”出现为止。若成员前面没有类似“public:”或“private:”,则所定义的成员是private(私有),这是类的默认设置。(3)关键字public和private可以在类中出现多次,且前后的顺序没有关系;但最好先声明公有成

2、员,后声明私有成员,因为public成员是用户最关心的。(4)除了public和private外,关键字protected(保护)也可修饰成员的类型,它与private两者基本相似,但在类的继承时有所不同(后面还会讲到)。(5)数据成员的类型可以是任意的,包含整型、浮点型、字符型、数组、指针和引用等,也可以是另一个类的对象。(6)尽量将类单独存放在一个文件中或将类的声明放在.h文件中而将成员函数的实现放在与.h文件同名的.cpp文件中。以后将会看到,VisualC+6.0为用户创建的应用程序框架中都是将各个类以.h和同名的.cpp文件组织的。第1页/共98页2.1.2 对象的定义一个类定义后,

3、就可以定义该类的对象,如下面的格式:其中,类名是用户已定义过的类的标识符,对象名可以有一个或多个,多个时要用逗号分隔。被定义的对象既可以是一个普通对象,也可以是一个数组对象或指针对象。例如:CMetermyMeter,*Meter,Meters2;这时,myMeter是类CMeter的一个普通对象,Meter和Meters分别是该类的一个指针对象和对象数组。一个对象的成员就是该对象的类所定义的数据成员(成员变量)和成员函数。访问对象的成员变量和成员函数和访问变量和函数的方法是一样的,只不过要在成员前面加上对象名和成员运算符“.”,其表示方式如下:.()第2页/共98页2.1.3 构造函数和析构

4、函数1.构造函数前面已提及,在类的定义中是不能对数据成员进行初始化的。为了能给数据成员自动设置某些初始值,这时就要使用类的特殊成员函数构造函数。构造函数的最大特点是在对象建立时它会被自动执行,因此用于变量、对象的初始化代码一般放在构造函数中。C+规定:构造函数必须与相应的类同名,它可以带参数,也可以不带参数,与一般的成员函数定义相同,也可以重载。例如:classCMeterpublic:CMeter(intnPos)/带参数的构造函数m_nPos=nPos;.这样若有:CMeteroMeter(10),oTick(20);则会自动调用构造函数CMeter(intnPos),从而使得对象oMet

5、er中的私有成员m_nPos的值为10;使得对象oTick中的私有成员m_nPos的值为20。第3页/共98页2.1.3 构造函数和析构函数2.析构函数与构造函数相对应的是析构函数。析构函数是另一个特殊的C+成员函数,它只是在类名称前面加上一个“”符号。每一个类只有一个析构函数,没有任何参数,也不返回任何值。例如:classCMeterpublic:.CMeter()/析构函数.析构函数只有在下列两种情况下才会被自动调用:(1)当对象定义在一个函数体中,该函数调用结束后,析构函数被自动调用。(2)用new为对象分配动态内存,当使用delete释放对象时,析构函数被自动调用。第4页/共98页2.

6、1.3 构造函数和析构函数3.默认构造函数和析构函数系统自动生成的默认构造函数和析构函数如下所示:CMeter()/默认构造函数的形式CMeter()/默认析构函数的形式需要说明的是,在用户定义一个对象时,编译器会自动根据对象定义的格式选择相应的构造函数。例如:CMeterm1,m2;由于m1和m2不带任何参数,当类没有用户定义的构造函数时,则编译器就会使用默认构造函数对m1和m2进行初始化。用默认构造函数对对象进行初始化时,则将对象的所有数据成员都初始化为零或空。第5页/共98页2.1.3 构造函数和析构函数4.构造函数的重载构造函数可以被重载,C+会根据对象定义中的参数选择合适的构造函数。

7、例如:例Ex_ConOverLoad 构造函数的重载#includeclassCDatepublic:CDate();CDate(intday);CDate(intmonth,intday);CDate(intyear,intmonth,intday);/其他公共成员private:intnYear,nMonth,nDay;CDate:CDate()nMonth=7;nDay=30;nYear=2002;coutnYear-nMonth-nDayendl;CDate:CDate(intday)第6页/共98页 nMonth=7;nDay=day;nYear=2002;coutnYear-nMo

8、nth-nDayendl;CDate:CDate(intmonth,intday)nMonth=month;nDay=day;nYear=2002;coutnYear-nMonth-nDayendl;CDate:CDate(intyear,intmonth,intday)nYear=year;nMonth=month;nDay=day;coutnYear-nMonth-nDayendl;voidmain()CDateday1;CDateday2(28);CDateday3(8,1);CDateday4(2003,3,10);运行结果为:第7页/共98页2.1.3 构造函数和析构函数例Ex_Co

9、nDefault 带默认参数的构造函数#includeclassCDatepublic:CDate(intyear=2002,intmonth=7,intday=30)nYear=year;nMonth=month;nDay=day;coutnYear-nMonth-nDayendl;/其他公共成员private:intnYear,nMonth,nDay;voidmain()CDateday1;CDateday2(2002,8);运行结果为:第8页/共98页2.1.3 构造函数和析构函数5.拷贝构造函数拷贝构造函数是一种特殊的成员函数,它的功能是用一个已知的对象来初始化一个被创建的同类的对象。

10、拷贝构造函数的函数名与构造函数一样,也是它所属类的类名。不过与一般的构造函数有一点不同,即它只有一个参数,且参数是同类的一个对象的引用。定义一个拷贝构造函数的一般形式如下::(const&)其中,const是一个类型修饰符,被它修饰的对象是一个不能被更新的常量。例如:第9页/共98页2.1.3 构造函数和析构函数例Ex_ConCopy 拷贝构造函数的使用#includeclassCDatepublic:CDate(intyear=2002,intmonth=7,intday=30)cout调用构造函数endl;nYear=year;nMonth=month;nDay=day;coutnYear

11、-nMonth-nDayendl;CDate(constCDate&ymd)/定义的拷贝构造函数cout调用拷贝构造函数endl;coutymd.nYear-ymd.nMonth-ymd.nDayendl;/其他公共成员private:intnYear,nMonth,nDay;voidmain()CDateday1(2002,8);CDateday2(day1);第10页/共98页2.1.3 构造函数和析构函数例Ex_ConCopy 拷贝构造函数的使用运行结果为:第11页/共98页2.1.3 构造函数和析构函数5.拷贝构造函数实际上,如果类中没有声明拷贝构造函数,则编译器自动生成一个默认的拷贝

12、构造函数。例如:例Ex_ConCopyDefault 默认拷贝构造函数的使用#includeclassCDatepublic:CDate(intyear=2002,intmonth=7,intday=30)cout调用构造函数endl;nYear=year;nMonth=month;nDay=day;voidoutput()coutnYear-nMonth-nDayendl;private:intnYear,nMonth,nDay;voidmain()CDateday1(2002,8);CDateday2(day1);/调用默认的拷贝函数day1.output();day2.output();

13、第12页/共98页2.1.3 构造函数和析构函数例Ex_ConCopyDefault 默认拷贝构造函数的使用运行结果为:第13页/共98页2.1.4 对象成员初始化前面所遇到的都是单独的一个类,但在实际应用中往往需要多个类,这时就可能把一个已定义类的对象作为另一个类的成员。为了能对这些对象成员进行初始化,C+允许采用这样的构造函数定义格式::(形参表):对象1(参数表),对象2(参数表),对象n(参数表)其中,对象1、对象2、对象n就是该类使用的其他类的对象,冒号“:”后面的列表称为成员初始化列表。下面来看一个示例:第14页/共98页2.1.4 对象成员初始化例Ex_InitMultObjec

14、t 对象成员的初始化#includeclassCPointpublic:CPoint(intx,inty)nPosX=x;nPosY=y;voidShowPos()cout当前位置:x=nPosX,y=nPosYendl;private:intnPosX,nPosY;classCSizepublic:CSize(intl,intw)nLength=l;nWidth=w;voidShowSize()cout当前大小:l=nLength,w=nWidthendl;private:intnLength,nWidth;第15页/共98页classCRectpublic:CRect(intleft,in

15、ttop,intright,intbottom):size(right-left,bottom-top),ptCenter(left+right)/2,(top+bottom)/2)voidShow()ptCenter.ShowPos();size.ShowSize();private:CPointptCenter;CSizesize;voidmain()CRectrc(10,100,80,250);rc.Show();运行结果为:代码中,声明类CRect的构造函数时,将成员CPoint类对象ptCenter和CSize类对象size按CRect构造函数的形参进行初始化。第16页/共98页2.

16、1.5 静态成员静态成员的提出是为了解决数据共享的问题。1.静态数据成员它是这样定义的:(1)使用关键字static声明静态数据成员。(2)对静态数据成员进行初始化。由于静态数据成员要实际在分配空间,因此不能在类声明中进行初始化。静态数据成员初始化在类的外部进行,且与一般数据成员初始化不同,它的格式如下::=例如:第17页/共98页2.1.5 静态成员例Ex_StaticData 静态数据成员的使用#includeclassCSumpublic:CSum(inta=0,intb=0)nSum+=a+b;intGetSum()returnnSum;voidSetSum(intsum)nSum=s

17、um;private:staticintnSum;/声明静态数据成员;intCSum:nSum=0;/静态数据成员的初始化voidmain()CSumone(10,2),two;coutsum=one.GetSum()endl;one.SetSum(5);coutsum=one.GetSum()endl;coutsum=two.GetSum()endl;运行结果为:第18页/共98页2.1.5 静态成员2.静态成员函数例Ex_StaticFunc 静态成员函数的使用#includeclassCSumpublic:CSum(inta=0,intb=0)nSum+=a+b;intGetSum()r

18、eturnnSum;voidSetSum(intsum)nSum=sum;staticvoidShowData(CSumone);/声明静态成员函数private:staticintnSum;voidCSum:ShowData(CSumone)/静态成员函数的实现cout直接使用静态成员endl;coutsum=nSumendl;cout使用同类的对象endl;coutsum=one.GetSum()endl;第19页/共98页intCSum:nSum=0;voidmain()CSumone(10,2);CSum:ShowData(one);/直接访问one.SetSum(8);one.Sho

19、wData(one);/通过对象访问运行结果为:第20页/共98页2.1.6 友元例Ex_FriendFunc 友元函数的使用#includeclassCPointpublic:CPoint()m_x=m_y=0;CPoint(unsignedx,unsignedy)m_x=x;m_y=y;voidPrint()coutPoint(m_x,m_y)endl;friendCPointInflate(CPoint&pt,intnOffset);/声明一个友元函数private:unsignedm_x,m_y;CPointInflate(CPoint&pt,intnOffset)/友元函数的定义CP

20、ointptTemp=pt;ptTemp.m_x+=nOffset;/直接改变私有数据成员m_x和m_y第21页/共98页ptTemp.m_y+=nOffset;returnptTemp;voidmain()CPointpt(10,20);pt.Print();pt=Inflate(pt,3);/调用友元函数pt.Print();运行结果为:第22页/共98页2.1.7 常类型常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。因此,定义或说明常类型时必须进行初始化。1.常对象常对象是指对象常量,定义格式如下:const定义常对象时,修饰符const可以放在类名

21、后面,也可以放在类名前面。例如:classCOnepublic:COne(inta,intb)x=a;y=b;private:intx,y;constCOnea(3,4);COneconstb(5,6);其中,a和b都是COne对象常量,初始化后就不能再被更新。第23页/共98页2.1.7 常类型2.常指针和常引用常指针也是使用关键字const来修饰的。但需要说明的是,const的位置不同,其含意也不同,它有三种形式。第一种形式是将const放在指针变量的类型之前,表示声明一个指向常量的指针。此时,在程序中不能通过指针来改变它所指向的数据值,但可以改变指针本身的值。例如:inta=1,b=2;

22、constint*p1=&a;/声明指向int型常的指针p1,指针地址为a的地址*p1=2;/错误,不能更改指针所指向的数据值p1=&b;/正确,指向常量的指针本身的值是可以改变的第二种形式是将const放在指针定义语句的指针名前,表示指针本身是一个常量,称为指针常量或常指针。因此,不能改变这种指针变量的值,但可以改变指变量所指向的数据值。例如:inta=1,b=2;int*constp1=&a;/声明指向int型常的指针p1,指针地址为a的地址int*constp2;/错误,在声明指针常量时,必须初始化*p1=2;/正确,指针所指向的数据值可以改变p1=&b;/错误,指针常量本身的值是不可改

23、变的第三种形式是将const在上述两个地方都加,表示声明一个指向常量的指针常量,指针本身的值不可改变,而且它所指向的数据的值也不能通过指针改变。例如:inta=1,b=2;constint*constpp=&a;*pp=2;/错误pp=&b;/错误第24页/共98页2.1.7 常类型例Ex_ConstPara常参数的函数传递#includeclassCOnepublic:voidprint(constint*p,intn)/使用常参数cout*p;for(inti=1;in;i+)cout,*(p+i);coutendl;voidmain()intarray6=1,2,3,4,5,6;COne

24、one;one.print(array,6);运行结果为:第25页/共98页2.1.7 常类型3.常成员函数使用const关键字进行声明的成员函数,称为“常成员函数”。只有常成员函数才有资格操作常量或常对象,没有使用const关键字说明的成员函数不能用来操作常对象。常成员函数说明格式如下:()const;其中,const是加在函数说明后面的类型修饰符,它是函数类型的一个组成部分,因此,在函数实现部分也要带const关键字。例如:第26页/共98页2.1.7 常类型例Ex_ConstFunc 常成员函数的使用#includeclassCOnepublic:COne(inta,intb)x=a;y

25、=b;voidprint();voidprint()const;/声明常成员函数private:intx,y;voidCOne:print()coutx,yendl;voidCOne:print()constcout使用常成员函数:x,yendl;voidmain()COneone(5,4);one.print();constCOnetwo(20,52);two.print();运行结果为:程序中,类COne声明了两个重载成员函数,一个带const,一个不带。语句“one.print();”调用成员函数“void print();”,而“two.print();”调用常成员函数“void pr

26、int()const;”。第27页/共98页2.1.7 常类型4.常数据成员类型修饰符const不仅可以说明成员函数,也可以说明数据成员。由于const类型对象必须被初始化,并且不能更新,此,在类中声明了const数据成员时,只能通过成员初始化列表的方式来生成构造函数对数据成员初始化。例如:例Ex_ConstData常数据成员的使用#includeclassCOnepublic:COne(inta):x(a),r(x)/常数据成员的初始化voidprint();constint&r;/引用类型的常数据成员private:constintx;/常数据成员staticconstinty;/静态常数

27、据成员;constintCOne:y=10;/静态数据成员的初始化voidCOne:print()coutx=x,y=y,r=rendl;voidmain()COneone(100);one.print();该程序的运行结果为:第28页/共98页2.1.8 this指针this指针是一个仅能被类的非静态成员函数所能访问的特殊指针。当一个对象调用成员函数时,编译器先将对象的地址赋给this指针,然后调用成员函数。例如,当下列成员函数调用时:one.copy(two);它实际上被解释成:copy(&one,two);只不过,&one参数为隐藏了。需要说明的是,通过*this可以判断是哪个对象来调用

28、该成员函数或重新指定对象。例如:第29页/共98页2.1.8 this指针例Ex_This this指针的使用#includeclassCOnepublic:COne()x=y=0;COne(inta,intb)x=a;y=b;voidcopy(COne&a);/对象引用作函数参数voidprint()coutx,yM这样的表达式中,其中pa是一个指向A类对象的指针。第32页/共98页2.1.9 类的作用域和对象的生存期对象的生存期是指对象从被创建开始到被释放为止的时间。按生存期的不同,对象可分为如下三种:(1)局部对象:当对象被定义时调用构造函数,该对象被创建,当程序退出定义该对象所在的函数

29、体或程序块时,调用析构函数,释放该对象。(2)静态对象:当程序第一次执行所定义的静态对象时,该对象被创建,当程序结束时,该对象被释放。(3)全局对象:当程序开始时,调用构造函数创建该对象,当程序结束时调用析构函数释放该对象。第33页/共98页2.2 继承和派生类2.2.1.单继承从一个基类定义一个派生类可按下列格式:class:;其中,继承方式有3种:public(公有)、private(私有)及protected(保护),若继承方式没有指定,则被指定为默认的public方式。继承方式决定了派生类的继承基类属性的使用权限,下面分别说明。第34页/共98页2.2.1.单继承1.公有继承(publ

30、ic)公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的。例如:classCStick:publicCMeterintm_nStickNum;/声明一个私有数据成员public:voidDispStick();/声明一个公有成员函数;/注意分号不能省略voidCStick:DispStick()m_nStickNum=GetPos();/调用基类CMeter的成员函数coutm_nStickNum;这时,从基类CMeter派生的CStick类除具有CMeter所有公有成员和保护成员外,还有自身的私有数据成员m_nStickNum和公有

31、成员函数DispStick()。这个完整的示例如下:第35页/共98页2.2.1.单继承例Ex_ClassPublicDerived 派生类的公有继承示例#includeclassCMeterpublic:CMeter(intnPos=10)m_nPos=nPos;CMeter()voidStepIt()m_nPos+;intGetPos()returnm_nPos;protected:voidSetPos(intnPos)m_nPos=nPos;private:intm_nPos;classCStick:publicCMeter/从CMeter派生,公有继承intm_nStickNum;/声

32、明一个私有数据成员public:voidDispStick();/声明一个公有成员函数voidSetStick(intnPos)SetPos(nPos);/类中调用基类的保护成员;第36页/共98页voidCStick:DispStick()m_nStickNum=GetPos();/调用基类CMeter的成员函数coutm_nStickNum;voidmain()CMeteroMeter(20);CStickoStick;coutCMeter:oMeter.GetPos(),CStick:oStick.GetPos()endl;oMeter.StepIt();coutCMeter:oMete

33、r.GetPos(),CStick:oStick.GetPos()endl;oStick.StepIt();outCMeter:oMeter.GetPos(),CStick:oStick.GetPos()endl;oStick.DispStick();oStick.StepIt();oStick.DispStick();运行结果为:第37页/共98页2.2.1.单继承2.私有继承(private)私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问。例如:例Ex_ClassPrivateDerived 派生类的私有继承示例#includeclassC

34、Meterpublic:CMeter(intnPos=10)m_nPos=nPos;CMeter()voidStepIt()m_nPos+;intGetPos()returnm_nPos;protected:voidSetPos(intnPos)m_nPos=nPos;private:intm_nPos;classCStick:privateCMeter/从CMeter派生,私有继承intm_nStickNum;/声明一个私有数据成员public:voidDispStick();/声明一个公有成员函数voidSetStick(intnPos)第38页/共98页SetPos(nPos);/调用基

35、类的保护成员intGetStick()returnGetPos();/调用基类的公有成员;voidCStick:DispStick()m_nStickNum=GetPos();/调用基类CMeter的成员函数coutm_nStickNum;voidmain()CMeteroMeter(20);CStickoStick;coutCMeter:oMeter.GetPos(),CStick:oStick.GetStick()endl;oMeter.StepIt();coutCMeter:oMeter.GetPos(),CStick:oStick.GetStick()endl;oStick.DispS

36、tick();运行结果为:第39页/共98页2.2.1.单继承3.保护继承(protected)保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的。表2.1列出三种不同的继承方式的基类特性和派生类特性。表2.1 不同继承方式的基类特性和派生类特性第40页/共98页2.2.2 派生类的构造函数和析构函数例Ex_ClassDerived 派生类的构造函数和析构函数的示例#include#includeclassCAnimalpublic:CAnimal(char*pName=noname);CAnimal();vo

37、idsetName(char*pName)strncpy(name,pName,sizeof(name);char*getName(void)returnname;private:charname20;CAnimal:CAnimal(char*pName)setName(pName);cout调用CAnimal的构造函数!endl;CAnimal:CAnimal()cout调用CAnimal的析构函数!endl;classCCat:publicCAnimal第41页/共98页public:CCat()cout调用CCat的构造函数!endl;CCat()cout调用CCat的析造函数!endl

38、;voidDispName()cout猫的名字是:getName()endl;voidmain()CCatcat;cat.DispName();cat.setName(Snoopy);cat.DispName();运行结果为:第42页/共98页2.2.2 派生类的构造函数和析构函数例如,在Ex_ClassPublicDerived示例中,CStick的构造函数可这样定义:classCStick:publicCMeter.public:CStick():CMeter(30).;此时再重新运行程序,结果就会变为:第43页/共98页2.2.3 多继承多继承下派生类的定义是按下面的格式:class:,

39、.;其中的继承方式还是前面的3种:public、private和protected。例如:classA.classB.classC:publicA,privateB.由于派生类C继承了基类A和B,具有多继承性,因此派生类C的成员包含了基类A中成员和B中成员以及该类本身的成员。第44页/共98页2.2.4虚基类一般说来,在派生类中对基类成员的访问应该是惟一的,但是,由于多继承情况下,可能造成对基类中某成员的访问出现了不惟一的情况,这种情况称为基类成员调用的二义性。例如:例Ex_Conflict 基类成员调用的二义性#includeclassApublic:intx;A(inta=0)x=a;cl

40、assB1:publicApublic:inty1;B1(inta=0,intb=0):A(b)y1=a;classB2:publicApublic:inty2;B2(inta=0,intb=0):A(b)y2=a;第45页/共98页;classC:publicB1,publicB2public:intz;C(inta,intb,intd,inte,intm):B1(a,b),B2(d,e)z=m;voidprint()coutx=xendl;/编译出错的地方couty1=y1,y2=y2endl;coutz=zendl;voidmain()Cc1(100,200,300,400,500);c

41、1.print();第46页/共98页2.2.4虚基类程序中,派生类B1和B2都从基类A继承,这时在派生类中就有两个基类A的拷贝。当编译器编译到“cout”x=“xendl;”语句时,因无法确定成员x是从类B1中继承来的,还是从类B2继承来,产生了二义性,从而出现编译错误。解决这个问题的方法之一是使用域作用运算符“:”来消除二义性,例如若将print()函数实现代码变为:voidprint()coutB1:x=B1:xendl;coutB2:x=B2:xendl;couty1=y1,y2=y2endl;coutz=zendl;重新运行,结果为:第47页/共98页2.3.1 虚函数先来看一个虚函

42、数应用实例。例Ex_VirtualFunc 虚函数的使用#includeclassCShapepublic:virtualfloatarea()/将area定义成虚函数return0.0;classCTriangle:publicCShapepublic:CTriangle(floath,floatw)H=h;W=w;floatarea()return(float)(H*W*0.5);private:floatH,W;第48页/共98页;classCCircle:publicCShapepublic:CCircle(floatr)R=r;floatarea()return(float)(3.1

43、4159265*R*R);private:floatR;voidmain()CShape*s2;s0=newCTriangle(3,4);coutarea()endl;s1=newCCircle(5);coutarea()area();”实际上是调用CTriangle类的area成员函数,结果是6;同样可以分析s1-area()的结果。需要说明的是:(1)虚函数在重新定义时参数的个数和类型必须和基类中的虚函数完全匹配,这一点和函数重载完全不同。(2)只有通过基类指针才能实现虚函数的多态性,若虚函数的调用是普通方式来进行的,则不能实现其多态性。(3)如果不使用new来创建相应的派生类对象指针,也

44、可使用通过&运算符来获取对象的地址。(4)虚函数必须是类的一个成员函数,不能是友元函数,也不能是静态的成员函数。(5)可把析构函数定义为虚函数,但不能将构造函数定义为虚函数。声明纯虚函数的一般格式为:virtual()=0;第50页/共98页2.3.2 纯虚函数和抽象类例Ex_PureVirtualFunc 纯虚函数和抽象类的使用#includeclassCShapepublic:virtualfloatarea()=0;/将area定义成纯虚函数;classCTriangle:publicCShapepublic:CTriangle(floath,floatw)H=h;W=w;floatar

45、ea()/在派生类定义纯虚函数的具体实现代码return(float)(H*W*0.5);private:floatH,W;classCCircle:publicCShapepublic:CCircle(floatr)第51页/共98页R=r;floatarea()/在派生类定义纯虚函数的具体实现代码return(float)(3.14159265*R*R);private:floatR;voidmain()CShape*pShape;CTriangletri(3,4);couttri.area()endl;pShape=&tri;coutarea()endl;CCirclecir(5);co

46、utcir.area()endl;pShape=○coutarea()endl;运行结果为:第52页/共98页2.4.1 运算符重载的语法定义一个运算符重载函数与定义普通函数相类似,只不过函数名必须以operator开头,其一般形式如下::operator()/函数体由于运算符重载函数的函数是以特殊的关键字开始的,编译器很容易与其他的函数名区分开来。先来看一个实例,这个例子是定义一个复数类CComplex,然后重载“+”运算符,使这个运算符能直接完成复数的加运算。第53页/共98页2.4.1 运算符重载的语法例Ex_Complex 运算符的简单重载#includeclassCCompl

47、expublic:CComplex(doubler=0,doublei=0)realPart=r;imagePart=i;voidprint()cout该复数实部=realPart,虚部=imagePartendl;CComplexoperator+(CComplex&c);/重载运算符+CComplexoperator+(doubler);/重载运算符+private:doublerealPart;/复数的实部doubleimagePart;/复数的虚部;CComplexCComplex:operator+(CComplex&c)/参数是CComplex引用对象第54页/共98页CCompl

48、extemp;temp.realPart=realPart+c.realPart;temp.imagePart=imagePart+c.imagePart;returntemp;CComplexCComplex:operator+(doubler)/参数是double类型数据CComplextemp;temp.realPart=realPart+r;temp.imagePart=imagePart;returntemp;voidmain()CComplexc1(12,20),c2(50,70),c;c=c1+c2;c.print();c=c1+20;c.print();运行结果为:第55页/共

49、98页2.4.2 友元重载实现运算符重载的方法有两种:用类的成员函数来实现和通过类的友元函数来实现。这里来用友元函数实现重载的方法。友元重载方法既可用于单目运算符,也可以用于双目运算符。它们的一般格式如下:friendoperator()/单目运算符重载/函数体friendoperator()/双目运算符重载/函数体重载函数来说,它有两个形参,这两个形参中必须有一个是类的对象。需要说明的是,有些运算符是不能重载为友元函数的,它们是:=、()、和-。第56页/共98页2.4.2 友元重载例Ex_ComplexFriend 运算符的友元重载#includeclassCComplexpublic:C

50、Complex(doubler=0,doublei=0)realPart=r;imagePart=i;voidprint()cout该复数实部=realPart,虚部=imagePartendl;CComplexoperator+(CComplex&c);/重载运算符+CComplexoperator+(doubler);/重载运算符+friendCComplexoperator+(doubler,CComplex&c);/友元重载运算符+friendCComplexoperator-(CComplex&c);/友元重载单目运算符-voidoperator+=(CComplex&c);priv

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 应用文书 > PPT文档

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁