C++程序设计第11章友元与运算符重载.ppt

上传人:小飞机 文档编号:6153991 上传时间:2023-09-30 格式:PPT 页数:71 大小:284.49KB
返回 下载 相关 举报
C++程序设计第11章友元与运算符重载.ppt_第1页
第1页 / 共71页
C++程序设计第11章友元与运算符重载.ppt_第2页
第2页 / 共71页
C++程序设计第11章友元与运算符重载.ppt_第3页
第3页 / 共71页
C++程序设计第11章友元与运算符重载.ppt_第4页
第4页 / 共71页
C++程序设计第11章友元与运算符重载.ppt_第5页
第5页 / 共71页
点击查看更多>>
资源描述

《C++程序设计第11章友元与运算符重载.ppt》由会员分享,可在线阅读,更多相关《C++程序设计第11章友元与运算符重载.ppt(71页珍藏版)》请在三一办公上搜索。

1、第11章 友元与运算符重载,目的与要求11.1 友元函数11.2 运算符重载11.3 多态性与虚函数11.4 类与对象的特性本章小结,目的与要求,通过本章的学习,应理解友元的概念,掌握将普通函数定义为类友元函数的方法。理解运算符重载的概念,掌握运算符重载函数的定义方法、调用过程及实际应用。掌握多态性技术的概念及实现方法。了解虚函数与纯虚函数的概念、定义格式及使用方法。,11.1 友元函数,友元函数定义:友元函数是能在类外访问类中的任何成员的函数。友元函数可以是普通函数,也可以是某个类的成员函数,甚至可以将某个类说明成另一个类的友元。,11.1.1 定义普通函数为友元函数,在定义一个类时,若在类

2、中用关键词friend修饰普通函数,则该普通函数就成为该类的友元函数,它可以访问该类中所有的成员。定义普通友元函数的格式为:friend(形参表);【例11.1】用友元函数的方法求长方体的体积。,例程,友元函数的说明:,(1)友元函数不是类的成员函数,它不带this指针。所以必须用对象或对象的引用作为友元函数的形参,并在函数体内使用运算符“.”来访问对象的成员(2)友元函数必须在类内进行函数原型说明,函数定义部分写在类外。(3)友元函数与一般函数的区别:友元函数可访问类内的任一数据成员或成员函数;一般函数只能访问类的公有数据成员或公有成员函数。(4)由于友元函数不是类的成员函数,所以类的访问权

3、限对友元函数不起作用。(5)友元函数可使用类内的所有成员,破坏了数据的安全性,使用友元函数必须谨慎。,11.1.2 友元注意事项,(1)友元关系是不传递的(2)友元关系不具有交换性(3)友元关系是不能继承的,11.2 运算符重载,11.2.1 运算符重载的概念 1引例 用“+”运算符完成两个实数、两个复数、两个字符串的相关运算。(1)实数。设:c1=10,c2=20,则:c1+c2=10+20=30。(2)复数。设:c1=10+10i,c2=20+20i,则:c1+c2=30+30i。(3)字符串。设:c1=“ABCD”,c2=“EFGH”,则c1+c2=ABCDEFGH“这就是“+”运算符的

4、重载。,运算符重载的概念,2运算符重载 所谓运算符重载就是用同一个运算符完成不同的运算操作。3运算符重载函数 运算符重载是通过运算符重载函数来完成的。运算符重载函数分一元运算符重载函数为成员函数、一元运算符重载函数为友员函数、二元运算符重载函数为成员函数、二元运算符重载函数为友员函数四种情况,11.2.2 二元运算符重载,1运算符重载函数为类的成员函数(1)重载函数的定义格式:(形参)函数体 其中,类型为重载函数的返回类型。类名为成员函数所属类的类名。关键词“operator”加上“重载运算符”为重载函数名,即:=。形参常为参加运算的对象或数据。,运算符重载函数为类的成员函数,(2)重载函数的

5、调用格式.(实参表);注意:在进行两个对象的二元运算时,其程序中所用到语法格式为:;如:c1+c2 而执行上述语句时,系统将自动转换成对重载函数的调用格式:.(右操作数);如c1.operator+(c2);【例11.2】定义一个复数类,重载“+”运算符,使这个运算符能直接完成两个复数的加法运算,以及一个复数与一个实数的加法运算。,例程,运算符重载函数为类的成员函数说明,(3)对于运算符重载,必须说明以下几点:运算符重载函数名必须为:operator 运算符的重载是通过调用运算符重载函数实现的。调用函数时,左操作数为调用重载函数的对象,右操作数作为函数的实参,实参可以是对象、实数等其它类型。形

6、参说明:若重载函数为成员函数,则参加二元运算的左操作数为调用重载函数的对象。因此,重载函数为成员函数的参数通常为一个,即右操作数。运算符重载函数的返回类型。若二个同类对象进行二元运算后的结果类型仍为原类型,则运算符重载函数的返回类型应为原类型。,C+中允许重载的运算符,(4)C+中允许重载的运算符如下表所示。,C+中不允许重载的运算符,(5)C+中不允许重载的运算符如下表所示。,2.运算符重载函数为友元函数,(1)重载运算符的定义格式(形参1,形参2)函数体 其中,形参1与形参2常为参加运算的两个对象的引用。当重载函数为友元普通函数时,该重载函数不能用对象调用,因此参加运算的两个对象必须以形参

7、方式传送到重载函数体内,所以形参通常为两个参加运算的对象。,运算符重载函数为友元函数,(2)重载函数的调用格式(实参1,实参2);其中实参1,实参2分别是重载运算符的左操作数和右操作数。【例11.3】用友元运算符重载函数实现【例11.2】中复数的加法运算。,例程,成员函数与友元函数作为重载函数的差别,(3)成员函数与友元函数作为重载函数的差别:用成员函数与友元函数作为运算符重载函数,就运算符的使用来讲是一样,但编译器处理方法是不同的。当重载函数为成员函数时,二元运算符的左操作数为调用重载函数的对象。右操作数为实参。当重载函数为友元函数时,二元运算符的左操作数为调用重载函数的第一个实参。右操作数

8、为第二个实参。,11.2.3 一元运算符重载,1.一元运算符重载函数为类的成员函数(1)重载函数的定义格式::operator(形参)函数体对典型一元运算符“+”、“”分前置与后置进行讨论。“+”为前置运算符,定义格式::operator+()函数体“+”为后置运算符,定义格式::operator+(int)函数体,一元运算符重载函数为类的成员函数,(2)重载函数的调用格式 前置“+”运算符,调用格式:.operator+();后置“+”运算符,调用格式:.operator+(1);【例11.4】定义一个描述时间计数器的类,其三个数据成员分别用于存放:时、分和秒。用成员函数重载“+”运算符,实

9、现计数器对象的加1运算。,例程,2.一元运算符重载函数为友元函数,(1)重载函数定义格式:operator(类名&对象)函数体 前置“+”运算符重载函数定义格式::operator+(类名&)函数体 后置“+”运算符重载函数定义格式::operator+(类名&,int)函数体 其中,int 只是用于区分是前置还是后置运算符,并无实际意义。,一元运算符重载函数为友元函数,(2)重载函数调用格式前置“+”运算符重载函数调用格式:operator+();后置“+”运算符重载函数的调用格式:operator+(,1);【例11.5】定义一个描述时间计数器的类,其三个数据成员分别用于存放:时、分和秒。

10、用友元函数重载“+”运算符,实现计数器对象的加1运算。【例11.6】定义描述三维空间点(x,y,z)的类,用成员函数实现空间两个点相加的“+”运算符重载,用友元函数实现空间一个点“+”运算符的重载。,例程,例程,11.2.4 字符串类运算符重载,举例说明字符串运算符重载函数的定义与调用方法,及重载后字符串运算符的使用方法。【例11.7】编写字符串运算符“=”与“+”的重载函数,使运算符“=”与“+”能完成两个字符串的赋值与拼接运算,实现字符串直接操作运算。分别用成员函数与友员函数编写重载函数。【例11.8】编写字符串运算符“”的重载函数,使运算符“”能完成两个字符串的比较运算,实现字符串直接比

11、较。分别用成员函数与友元函数编写重载函数。,例程,例程,11.3 多态性与虚函数,11.3.1 多态性技术1.多态性技术的概念(1)多态性技术:调用同名函数完成不同的函数功能,或使用同名运算符完成不同的运算功能。(2)多态性常用重载技术与虚函数来实现。(3)多态性分为两类:编译时的多态性和运行时的多态性。,多态性技术,2编译时的多态性 通过函数的重载或运算符的重载来实现的。也称静态多态性。3运行时的多态性 运行时的多态性也称为动态多态性,运行时的多态性是指在程序执行前,根据函数名和参数无法确定应该调用哪一个函数,必须在程序执行过程中,根据具体执行情况来动态地确定。运行时的多态性是通过类的继承关

12、系和虚函数来实现的。,11.3.2 虚函数,1虚函数概念 在基类中用关键字 virtual修饰的成员函数称为虚函数。2虚函数定义格式 virtual(参数)函数体,3用虚函数实现动态多态性的方法,(1)在基类中定义虚函数(2)在派生类中定义与基类虚函数同名同参数同返回类型的成员函数,即派生类中的虚函数。(3)在主函数中操作步骤:用基类定义指针变量。将基类对象地址或派生类对象地址赋给该指针变量。用(实参);方式去调用基类或派生类中的虚函数。,用虚函数实现动态多态性举例,【例11.9】定义基类High,数据成员为高H,定义成员函数Show()为虚函数。然后再由High派生出长方体类Cuboid与圆

13、柱体类Cylinder。并在两个派生类中定义成员函数Show()为虚函数。在主函数中,用基类High定义指针变量p,然后用指针p动态调用基类与派生类中虚函数Show(),显示长方体与圆柱体的体积。关于虚函数有几点说明:(1)派生类虚函数必须与基类虚函数同名同参数同返回类型。(2)实现动态的多态性时,必须使用基类类型的指针变量,使该指针指向不同派生类的对象,并通过调用指针所指向的虚函数才能实现动态的多态性。,例程,虚函数的说明,(3)虚函数必须是类的一个成员函数,不能是友元函数,也不能是静态的成员函数。(4)若派生类中没有定义虚函数,将派生类对象地址赋给基类定义的指针变量后,用指针变量虚函数(实

14、参);方式去调用虚函数时,调用的虚函数是基类的虚函数。(5)可将析构函数定义为虚函数,但不能将构造函数定义为虚函数。(6)虚函数与一般函数相比较,调用时执行速度要慢一些。为了实现多态性。在每一个派生类中均要保持相应虚函数的入口地址表,函数调用机制也是间接实现的。,11.3.3 纯虚函数,1.纯虚函数的概念 在定义一个基类时,若无法定义基类中虚函数的具体操作,虚函数的具体操作完全取决于其不同的派生类。这时,可将基类中的虚函数定义为纯虚函数。2.纯虚函数定义格式:virtual(形参表)=0;3.纯虚函数特点:(1)纯虚函数无函数体,在派生类中没有重新定义纯虚函数之前,不能调用该函数。(2)将函数

15、名赋值为0的含义是,将指向函数体的指针值赋初值0。,纯虚函数特点,(3)将至少包含一个纯虚函数的类称为抽象类。这种类只能作为派生类的基类,不能用来说明对象。【例11.10】定义抽象基类High,数据成员为高H,定义Show()为纯虚函数。然后再由High派生出长方体类Cuboid与圆柱体类Cylinder。并在两个派生类中重新定义虚函数Show()。在主函数中,用基类High定义指针变量p,然后用指针p动态调用派生类中虚函数Show(),显示长方体与圆柱体的体积。(4)在以抽象类作为基类的派生类中必须有纯虚函数的实现部分,即必须有重载纯虚函数的函数体。否则,这样的派生类也是不能产生对象的。,例

16、程,11.4 类与对象的特性,1.封装性2.派生与继承性3.多态性4.对象的消息机制,本章小结,1.友元 为了能在类外直接使用类的私有成员或保护成员,C+提供了友元。将普通函数定义为某类的友元函数的方法,是在该类中增加用freind修饰的普通函数原型说明:friend(形参);此时,可在 中使用类的私有成员或保护成员。,2.运算符重载,运算符重载是指用同一运算符完成不同的运算操作。运算符重载是通过运算符重载函数来实现的。运算符重载函数分为一元运算符重载函数和二元运算符重载函数。运算符重载函数可通过成员函数或友元函数来实现。,(1)二元运算符重载函数,用成员函数重载运算符::(形参)函数体 在执

17、行运算符操作时,编译器将对运算符的操作解释为对运算符成员重载函数的调用,并将运算符左操作数作为调用重载函数的对象,右操作数作为重载函数的实参。即重载成员函数的调用形式为:.(右操作数);,二元运算符重载函数,用友元函数重载运算符 重载函数作为普通友元函数一般应写在类外。在类中作引用性说明:friend(形参1,形参2)函数体 在执行运算符操作时,编译器将对运算符的操作解释为对运算符友元重载函数的调用,并将运算符左、右操作数作为调用友元重载函数的实参。即重载友员函数的调用形式为:(左操作对象,右操作对象);,(2)一元运算符重载函数,用成员函数重载“+”运算符前置+::()后置+::(int)用

18、友元函数重载“+”运算符前置+:friend:(类名&)后置+:friend:(类名&,int)其中形参中的int 只用于区别前置+重载函数,还是后置+重载函数,并无整型参数的含义。对于前置+成员函数,必须用this指针返回自加结果。,(3)字符串运算符重载函数,使用字符串运算符重载函数,可使字符串拷贝、拼接、比较等操作直接用字符串运算符“=”、“+”、“”、“”来进行。字符串常进行二元运算,其重载函数的定义格式与二元运算符重载函数相同。,3.多态性技术,多态性技术是指调用同名函数完成不同的函数功能,或使用同名运算符完成不同的运算功能。它常用重载函数与虚函数来实现。函数重载或运算符重载均属于编

19、译时的多态性,而虚函数则属于运行时的多态性。,4.虚函数,在基类中用关键字 virtual修饰的成员函数称为虚函数,定义格式为:virtual(参数)函数体 用虚函数实现“运行时的多态性”的方法是:在派生类中定义与基类虚函数同名同参数同返回类型的虚函数,用基类定义指针变量p,将基类或派生类对象的地址赋给p(即p=&对象)后,用p-虚函数,则可实现“运行时的多态性”。,5.纯虚函数,将函数名赋0值且无函数体的虚函数称为纯虚函数,定义格式为:virtual(参数)=0;含有纯虚函数的类称为抽象类,不能用抽象类定义对象。因为纯虚函数无函数体,所以纯虚函数不能调用,因此必须在派生类中重新定义虚函数。,

20、例11.1,#include class Cuboid private:float Length,Width,High;public:Cuboid(float l,float w,float h)/构造函数 Length=l;Width=w;High=h;friend float Volume(Cuboid/调用友元函数求体积,返回,例11.2(1),#include class Complex private:float Real,Image;public:Complex(float r=0,float i=0)Real=r;Image=i;void Show(int i)coutci=Re

21、al+Imageiendl;Complex operator+(Complex,例11.2(2),Complex Complex:operator+(float s)Complex t;t.Real=Real+s;t.Image=Image;return t;void main(void)Complex c1(25,50),c2(100,200),c3;c1.Show(1);c2.Show(2);c3=c1+c2;/c3=(25+50i)+(100+200i)=125+250i c3.Show(3);c1=c1+200;/c1=25+50i+200=225+50i c1.Show(1);,返回

22、,例11.3(1),#include class Complex private:float Real,Image;public:Complex(float r=0,float i=0)Real=r;Image=i;void Show(int i)coutci=Real+Imageiendl;friend Complex operator+(Complex,例11.3(2),Complex operator+(Complex,例11.3(3),void main(void)Complex c1(25,50),c2(100,200),c3;c1.Show(1);c2.Show(2);c3=c1+

23、c2;/c3=(25+50i)+(100+200i)=125+250i c3.Show(3);c1=c1+200;/c1=25+50i+200=225+50i c1.Show(1);,返回,例11.4(1),#include class TCount/定义计数器类TCount private:int Hour,Minute,Second;/数据成员时、分、秒 public:TCount(int h=0,int m=0,int s=0)/定义默认值为0的构造函数 Hour=h;Minute=m;Second=s;TCount operator+();/定义“前置+”运算符重载成员函数 TCoun

24、t operator+(int);/定义“后置+”运算符重载成员函数 void Show(int i)/定义显示时:分:秒的成员函数 coutti=Hour:Minute:Secondendl;,例11.4(2),TCount TCount:operator+()/定义“前置+”运算符重载函数(无形参)Second+;/秒单元加1 if(Second=60)/秒单元满60,清0后分单元加1 Second=0;Minute+;if(Minute=60)/分单元满60后,清0时单元加1 Minute=0;Hour+;if(Hour=24)Hour=0;return*this;,例11.4(3),T

25、Count TCount:operator+(int)/定义“后置+”运算符重载函数(有int)TCount temp=*this;Second+;if(Second=60)Second=0;Minute+;if(Minute=60)Minute=0;Hour+;if(Hour=24)Hour=0;return temp;,例11.4(4),void main(void)TCount t1(10,25,50),t2,t3;/定义时间计数器对象t1=10:25:50 t1.Show(1);t2=+t1;/先加后用,即:先将t1自加,然后将t1赋给t2 t1.Show(1);t2.Show(2);

26、t3=t1+;/先用后加,即:先将t1赋给t3,然后将t1自加 t1.Show(1);t3.Show(3);,返回,例11.5(1),#include class TCount private:int Hour,Minute,Second;public:TCount()Hour=Minute=Second=0;TCount(int h,int m,int s)Hour=h;Minute=m;Second=s;friend TCount,例11.5(2),TCount/返回自加后的对象t,例11.5(3),TCount operator+(TCount/返回加1前的t值,例11.5(4),voi

27、d main(void)TCount t1(10,25,50),t2,t3;/t1=10:25:50 t1.Show(1);t2=+t1;/先加后用 t1.Show(1);t2.Show(2);t3=t1+;/先用后加 t1.Show(1);t3.Show(3);,返回,例11.6(1),#include class ThreeD float x,y,z;public:ThreeD(float a=0,float b=0,float c=0)x=a;y=b;z=c;ThreeD operator+(ThreeD,例11.6(2),ThreeD,例11.6(3),void main(void)T

28、hreeD m1(25,50,100),m2(1,2,3),m3;m1.Show();+m1;m1.Show();m2+;m2.Show();m3=+m1+m2+;m3.Show();,返回,例11.7.1 用成员函数的程序设计(1),#include#include class String/定义字符串类 private:int Length;char*Sp;public:String()/定义默认的构造函数 Sp=0;Length=0;String(const char*s)/定义有参构造函数 Length=strlen(s);Sp=new charLength+1;strcpy(Sp,s

29、);,例11.7.1 用成员函数的程序设计(2),void Delete()/定义动态回收内存函数 if(Sp)delete Sp;void Show()/定义显示字符串函数 coutSpendl;void operator=(String,例11.7.1 用成员函数的程序设计(3),void String:operator=(String,例11.7.1 用成员函数的程序设计(4),void main(void)String s1(software and),s2(hardware),s3;s1.Show();s2.Show();s3=s1+s2;s3.Show();s1.Delete();

30、s2.Delete();s3.Delete();,例11.7.2 用友元函数的程序设计,将String类中“+”重载函数的原型说明改为友元函数说明如下:friend String operator+(String,返回,例11.8(1),#include#include class String/定义字符串类 private:int Length;char*Sp;public:String(char*s)/定义有参构造函数 Length=strlen(s);Sp=new charLength+1;strcpy(Sp,s);,例11.8(2),String()/定义析构函数 if(Sp)dele

31、te Sp;void Show()/定义显示字符串函数 cout(String,返回,例11.9(1),#include class High protected:float H;public:High(float h)H=h;virtual void Show()/在基类中定义虚函数Show()coutHigh=Hendl;,例11.9(2),class Cuboid:public High private:float Length,Width;public:Cuboid(float l=0,float w=0,float h=0):High(h)Length=l;Width=w;void

32、Show()/在长方体派生类中定义虚函数Show()coutLength=Lengtht;coutWidth=Widtht;coutHigh=Hn;coutCuboid Volume=Length*Width*Hendl;,例11.9(3),class Cylinder:public High private:float R;public:Cylinder(float r=0,float h=0):High(h)R=r;void Show()/在圆柱体派生类中定义虚函数Show()coutRadius=Rt;coutHigh=Hn;coutCylinder Volume=R*R*3.1415*

33、Hendl;,例11.9(4),void main(void)High h(10),*p;Cuboid cu(10,10,10);Cylinder cy(10,10);p=,返回,例11.10(1),#include class High protected:float H;public:High(float h)H=h;virtual void Show()=0;/在基类中定义纯虚函数Show();,例11.10(2),class Cuboid:public High private:float Length,Width;public:Cuboid(float l=0,float w=0,f

34、loat h=0):High(h)Length=l;Width=w;void Show()/在长方体派生类中定义虚函数Show()coutLength=Lengtht;coutWidth=Widtht;coutHigh=Hn;coutCuboid Volume=Length*Width*Hendl;,例11.10(3),class Cylinder:public High private:float R;public:Cylinder(float r=0,float h=0):High(h)R=r;void Show()/在圆柱体派生类中定义虚函数Show()coutRadius=Rt;coutHigh=Hn;coutCylinder Volume=R*R*3.1415*Hendl;,例11.10(4),void main(void)High*p;Cuboid cu(10,10,10);Cylinder cy(10,10);p=,返回,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号