《多态性和虚函数》PPT课件.ppt
《《多态性和虚函数》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《多态性和虚函数》PPT课件.ppt(141页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、多态性和虚函数多态性和虚函数 l封装性是基础,继承性是关键,多态性是补充封装性是基础,继承性是关键,多态性是补充l多态性是指发出同样的消息被不同类型的对象接收多态性是指发出同样的消息被不同类型的对象接收时导致完全不同的行为:时导致完全不同的行为:函数和运算符重载函数和运算符重载 虚函数、虚函数、动态联编动态联编1 函数重载函数重载l函数重载就是赋给同一个函数名多个含义lC中允许在相同的作用域内以相同的名字定义几个不同实现的函数,可以使成员函数,也可以是非成员函数l要求函数的参数或者至少有一个类型不同,或者个数不同l参数个数和类型都相同,仅仅返回值不同的重载函数是非法的例例 构造函数进行重载#i
2、nclude#includeclassstringpublic:string(char*s);string(string&s1);string(intsize=80);string()deletesptr;intgetlen()returnlength;voidprint()coutsptrendl;private:char*sptr;intlength;string:string(char*s)length=strlen(s);sptr=newcharlength+1;strcpy(sptr,s);string:string(string&s1)length=s1.length;sptr=n
3、ewcharlength+1;strcpy(sptr,s1.sptr);string:string(intsize)length=size;sptr=newcharlength+1;*sptr=0;voidmain()stringstr1(Thisisastring.);str1.print();coutstr1.getlen()endl;char*s1=Thatisaprogram.;stringstr2(s1);stringstr3(str2);str3.print();coutstr3.getlen()endl;Ans:Thisisastring.17Thatisaprogram.18函
4、数重载应注意问题:l不要使用重载函数来描述毫无相干的函数l构造函数可以重载,普通成员函数也可以重载l在重载函数中使用缺省函数参数时应注意调用的二义性,例如:voidprint(inta,intb)couta=a,b=bendl;voidprint(inta,intb,intc=50)couta=a,b=bendl;下列函数调用,由于二义性将通不过:print(10,100);2 运算符重载运算符重载l运算符重载就是赋予已有的运算符多重含义lC中通过重新定义运算符,使它能够用于特定类的对象执行特定的功能l增强了C语言的扩充能力2.1 运算符重载的概念 l为了介绍运算符重载的概念,先看一个运算符重
5、载的引例。引例:用“+”运算符完成两个实数、两个复数、两个字符串的相关运算。(1)实数设有两个实数:x1=10,x2=20,则两个实数相加的结果是:x1+x2=10+20=30。(2)复数设有两个复数:x1=10+10i,x2=20+20i,则两复数相加结果是:x1+x2=30+30i。(3)字符串设有两个字符串:x1=“ABCD”,x2=“EFGH”,则两字符串连接的结果:x1+x2=ABCDEFGH2.1 运算符重载的概念由上例可以看出,同一个运算符“+”可用于完成实数加法、复数加法及字符串连接等不同的运算,得到完全不同的结果。这就是“+”运算符的重载。因此,所谓运算符重载就是用同一个运算
6、符完成不同的运算操作。在C+这类面向对象的程序设计语言中,运算符重载可以完成两个对象的复杂操作(如:两个复数的算术运算等)。而运算符重载是通过运算符重载函数来完成的。当编译器遇到重载运算符,如复数加法:x1+x2中的加号运算符“+”时,自动调用“+”运算符的重载函数完成两个复数对象的加法操作。由于二元运算符的重载函数与一元运算符的重载函数有较大区别,因此分开介绍。先介绍二元运算符重载函数,再介绍一元运算符重载函数。2.2 二元运算符重载函数 l运算符重载函数可以是类的成员函数或者是友元函数。2.2 二元运算符重载函数l1运算符重载函数为类的成员函数运算符重载函数为类的成员函数一般定义格式为::
7、(形参表)函数体其中,类型为运算符重载函数的返回类型。类名为成员函数所属类的类名。关键词“operator”加上“重载运算符”为重载函数名,即:重载函数名=operator重载运算符。形参常为参加运算的对象或数据。2.2 二元运算符重载函数l例定义一个复数类,重载“=”运算符,使这个运算符能直接完成复数的赋值运算。#includeclassComplexprivate:floatReal,Image;public:Complex(floatr=0,floati=0)Real=r;Image=i;/缺省构造函数voidShow(inti)/显示输出复数coutci=Real+Imageiendl
8、;voidoperator=(Complex&c)/“=”运算符重载函数完成复数赋值操作Real=c.Real;Image=c.Image;voidmain(void)Complexc1(25,50),c2;c1.Show(1);c2=c1;c2.Show(2);程序执行后输出:c1=25+50ic2=25+50i在程序中,定义了一个赋值运算符“=”的重载函数:voidoperator=(Complex&c)Real=c.Real;Image=c.Image;2.2 二元运算符重载函数l该重载函数的函数名为“operator=”,返回类型为void,形参为复数类对象的引用Complex&c。当
9、程序执行主函数中的赋值语句c2=c1而遇到赋值运算符“=”时,自动调用赋值运算符“=”重载函数“operator=()”,并将“=”运算符右边的操作数c1作为实参,左边操作数c2作为调用重载函数的对象,即:作了一次c2.operator=(c1)的函数调用。在函数的调用过程中,实参c1传给形参c,在函数体内完成了复数实部与虚部的赋值操作:Real=c1.Real;Image=c1.Image;2.2 二元运算符重载函数l在上例定义复数类中,重载“+”、“”运算符,使这二个运算符能直接完成复数的加、减运算。#includeclassComplexprivate:floatReal,Image;p
10、ublic:Complex(floatr=0,floati=0)Real=r;Image=i;voidShow(inti)/显示输出复数coutci=Real+Imageiendl;Complexoperator+(Complex&c);/“+”运算符重载函数完成两个复数加法Complexoperator-(Complex&c);/“”运算符重载函数完成两个复数减法Complexoperator+(floats);/“+”运算符重载函数完成复数实部加实数voidoperator+=(Complex&c);/“+=”运算符重载函数完成复数=复数+cvoidoperator=(Complex&c)
11、;/“=”运算符重载函数完成两个复数赋值;ComplexComplex:operator+(Complex&c)Complext;t.Real=Real+c.Real;t.Image=Image+c.Image;returnt;ComplexComplex:operator-(Complex&c)Complext;t.Real=Real-c.Real;t.Image=Image-c.Image;returnt;ComplexComplex:operator+(floats)Complext;t.Real=Real+s;t.Image=Image;returnt;voidComplex:oper
12、ator+=(Complex&c)Real=Real+c.Real;Image=Image+c.Image;voidComplex:operator=(Complex&c)Real=c.Real;Image=c.Image;voidmain(void)Complexc1(25,50),c2(100,200),c3,c4;c1.Show(1);c2.Show(2);c3=c1+c2;/c3=(25+50i)+(100+200i)=125+250ic3.Show(3);c4=c2-c1;/c4=(100+200i)(25+50i)=75+150ic4.Show(4);c2+=c1;/c2=c2+c
13、1=(100+200i)+(25+50i)=125+250ic2.Show(2);c1=c1+200;/c1=(25+50i)+200=225+50ic1.Show(1);l执行程序后输出:c1=25+50ic2=100+200ic3=125+250ic4=75+150ic2=125+250ic1=225+50i2.2 二元运算符重载函数l在上例中的主函数中可以看出,经重载后运算符的使用方法与普通运算符一样方便。如复数c1加c2赋给c3的加法运算:c3=c1+c2与普通实数加法形式上完全相同。但实际执行过程中确是完全不同的。实现复数加法运算是通过调用加法运算符重载函数来完成,而对加法运算符重载
14、函数的调用是由系统自动完成的。如表达式:c3=c1+c2;编译器先将c1+c2解释为对“+”运算符重载函数:c1.operator+(c2)的调用。再将该表达式解释为对“=”运算符重载函数:c4.operator=(c1.operator+(c2)的调用。由c1.operator+(c2)成员函数求出复数c1+c2的值t,并返回一个计算结果t,然后再由成员函数c3.operator=(t),完成复数c3=t的赋值运算,将运算结果赋给c3。运算符重载的几个问题运算符重载的几个问题(1)运算符重载函数名必须为:operator(2)运算符的重载是通过调用运算符重载函数实现的,调用函数时,左操作数为
15、调用重载函数的对象,右操作数作为函数的实参,实参可以是对象、实数等其它类型。(3)形参说明若重载函数为成员函数,则参加二元运算的左操作数为调用重载函数的对象。因此,重载函数为成员函数的参数通常为一个,即右操作数。如在上例中,二元加法运算:c1+c2被解释为对重载成员函数c1.operator+(c2)的调用,此时重载函数只有一个参数。运算符重载的几个问题运算符重载的几个问题(4)运算符重载函数的返回类型若二个同类对象进行二元运算后的结果类型仍为原类型,则运算符重载函数的返回类型应为原类型。如在上例中,由于两个复数运算的结果仍为复数,因此上述运算符重载函数的返回类型均为复数类型Complex。运
16、算符重载的几个问题运算符重载的几个问题(5)除了下面几个外,其余的运算符都可以用作重载。下列运算符不允许重载:运算符运算符的含义不允许重载的原因?:三目运算符在C+中没有定义一个三目运算符的语法成员操作符为保证成员操作符对成员访问的安全性,故不允许重载*成员指针操作符同上:作用域运算符因该操作符左边的操作数是一个类型名,而不是一个表达式sizeof求字节数操作符其操作数是一个类型名,而不是一个表达式运算符重载的几个问题运算符重载的几个问题(6)运算符的重载实际上是函数的重载,对运算符重载的选择,遵循着函数重载的选择原则。重载运算符有以下各种限制:不可臆造新的运算符 不能改变运算符操作数的个数;
17、不能改变运算符原有的优先级;不能改变运算符原有的结合性;不能改变运算符原有的语法结构2运算符重载函数为友元函数l运算符重载函数为友元函数的一般定义格式为:(形参1,形参2)函数体其中,类型为运算符重载函数的返回类型。operator为重载函数名。形参1与形参2常为参加运算的两个对象的引用。例:用友元运算符重载函数实现复数的加、减运算。#includeclassComplexprivate:floatReal,Image;public:Complex(floatr=0,floati=0)Real=r;Image=i;voidShow(inti)coutci=Real+Imageiendl;fri
18、endComplexoperator+(Complex&,Complex&);/“+”重载函数为友元函数friendComplexoperator-(Complex&,Complex&);/“”重载函数为友元函数friendComplexoperator+(Complex&,float);Complexoperator+(Complex&c1,Complex&c2)Complext;t.Real=c1.Real+c2.Real;t.Image=c1.Image+c2.Image;returnt;Complexoperator-(Complex&c1,Complex&c2)Complext;t.
19、Real=c1.Real-c2.Real;t.Image=c1.Image-c2.Image;returnt;Complexoperator+(Complex&c,floats)Complext;t.Real=c.Real+s;t.Image=c.Image;returnt;voidmain(void)Complexc1(25,50),c2(100,200),c3,c4;c1.Show(1);c2.Show(2);c3=c1+c2;/c3=(25+50i)+(100+200i)=125+250ic3.Show(3);c4=c2c1;/c4=(100+200i)(25+50i)=75+150ic
20、4.Show(4);c1=c1+200;/c1=25+50i+200=225+50ic1.Show(1);2运算符重载函数为友元函数l程序执行后输出:c1=25+50ic2=100+200ic3=125+250ic4=75+150ic1=225+50i2运算符重载函数为友元函数l从主函数可以看出,用成员函数与友元函数为运算符重载函数,就运算符的使用来讲是一样,但编译器处理方法是不同的,例如对表达式:c3=c1+c2;的处理是,先将c1+c2变换为对友元函数的调用:operator+(c1,c2);再将函数返回结果即两复数的和t赋给复数c3,因此表达式c3=c1+c2;实际执行了c3=opera
21、tor+(c1,c2)的函数调用及赋值工作。l友元函数与成员函数作为二元运算符重载函数的另一个区别是:当重载函数为成员函数时,二元运算符的左操作数为调用重载函数的对象。右操作数为实参。当重载函数为友元函数时,二元运算符的左操作数为调用重载函数的第一个实参。右操作数为第二个实参。2.3 一元运算符的重载 l所谓一元运算符是只有一个操作数的运算符,如自加运算符“+”,自减运算符“”等等。与二元运算符的重载类似,一元运算符重载函数也分为类的成员函数与友元函数两类。2.3 一元运算符的重载1一元运算符重载函数为类的成员函数格式::operator(形参)函数体现对比较典型的一元运算符“+”、“”进行讨
22、论。对于一元运算符“+”、“”存在前置与后置问题,因此定义函数时会有所区别。2.3 一元运算符的重载(1)“+”为前置运算符时,函数格式为::operator+()函数体(2)“+”为后置运算符时,函数格式为:operator+(int)函数体由于是用运算符重载函数来实现“+”运算,所以这里的“+”是广义上的增量运算符。在后置运算符重载函数中,形参int仅用作区分前置还是后置,并无实际意义,可以给一个变量名,也可不给出变量名。例:定义一个描述时间计数器的类,其三个数据成员分别用于存放时、分和秒。用成员函数重载“+”运算符,实现计数器对象的加1运算。#includeclassTCountpriv
23、ate:intHour,Minute,Second;public:TCount(inth=0,intm=0,ints=0)Hour=h;Minute=m;Second=s;TCountoperator+();/定义“前置+”运算符重载成员函数TCountoperator+(int);/定义“后置+”运算符重载成员函数voidShow(inti)/定义显示时:分:秒的成员函数coutti=Hour:Minute:Secondendl;TCountTCount:operator+()Second+;if(Second=60)Second=0;Minute+;if(Minute=60)Minute=
24、0;Hour+;if(Hour=24)Hour=0;return*this;TCountTCount:operator+(int)TCounttemp=*this;Second+;if(Second=60)Second=0;Minute+;if(Minute=60)Minute=0;Hour+;if(Hour=24)Hour=0;returntemp;voidmain(void)TCountt1(10,25,50),t2,t3;/定义时间计数器对象t1=10:25:50t1.Show(1);t2=+t1;/先加后用,即:先将t1自加,然后将t1赋给t2t1.Show(1);t2.Show(2)
25、;t3=t1+;/先用后加,即:先将t1赋给t3,然后将t1自加t1.Show(1);t3.Show(3);2.3 一元运算符的重载l程序执行后输出:t1=10:25:50t1=10:25:51t2=10:25:51t1=10:25:52t3=10:25:512.3 一元运算符的重载l说明:(1)“前置+”运算符重载成员函数的说明在主函数中执行t2=+t1语句时,先将t1自加,然后将t1赋给t2。该语句操作是通过调用“前置+”运算符重载成员函数来实现的。在执行t2=+t1语句时,编译系统将t2=+t1解释为对重载函数的调用:t2=t1.operator+();由于重载函数为对象t1成员函数,所
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 多态性和虚函数 多态性 函数 PPT 课件
限制150内