《函数与运算符的重.ppt》由会员分享,可在线阅读,更多相关《函数与运算符的重.ppt(91页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第5 5章章 函数,函数与运算符的重载函数,函数与运算符的重载要点要点 函数函数 函数的重载函数的重载 运算符的重载运算符的重载1n函数:参数化的子程序;函数:参数化的子程序;n从从SP的观点,函数:程序长度的观点,函数:程序长度;整个程序整个程序子任务子任务;n从运算的角度,函数从运算的角度,函数:C+提供的用户定义提供的用户定义 的运算。运算符的运算。运算符:系统提供的运算系统提供的运算;n作为作为OOP的的C+,类,类:核心,类核心,类=数据数据+方法,方法,方法方法/类的函数成员类的函数成员:对数据的运算和处理。对数据的运算和处理。函数在函数在C+中的意义中的意义2例:按照例:按照C
2、ardan公式,计算公式,计算3次方程次方程x3+px+q=0 的一个实根:的一个实根:5.1 3次方程求根程序的设计次方程求根程序的设计方法:方法:(1)计算浮点数的立方根的程序作为函数计算浮点数的立方根的程序作为函数 (2)主程序中主程序中2次调用该函数次调用该函数 (3)计算计算 迭代公式:迭代公式:rn+1=2/3*rn+y/(3rn2)3#include#includefloat cuberoot(float);/原型原型void main(void)float p,q,xr;coutpq;float a=sqrt(q/2*q/2+p/3*p/3*p/3);/xr=cuberoot(
3、-q/2+a)+cuberoot(-q/2-a);coutendlThe real root of the equation is eps);return(croot);5执行结果执行结果6 属性说明属性说明 类型类型 函数名函数名(参数表参数表);5.2 函数的说明与使用函数的说明与使用1.1.函数说明函数说明函数原型函数原型/声明声明-指出函数的名称,类型和参数指出函数的名称,类型和参数例:例:int add(int a,int b);inline void swap(float&,float&);void print(char*);可省略可省略7oinline:内联函数内联函数 P125
4、ostatic:静态函数静态函数 P170ovirtual:虚函数虚函数 P202ofriend:某类的友元函数某类的友元函数 P170 属性说明属性说明 类型类型 函数名函数名(参数表参数表);可缺省可缺省属性说明属性说明函数的返函数的返回类型回类型标识符标识符除除main()函数和类的构造函数和类的构造/析构函数之析构函数之外,所有函数必须指出返回类型外,所有函数必须指出返回类型8例:例:/program 7_1.cppclass stack float datamaxsize;int top;public:stack(void);/构造函数构造函数 P168 stack(void);/析
5、构函数析构函数 P169 ;stack:stack(void)top=0;coutstack initialized.endl;9例:例:class point /point:平面上一点平面上一点private:float Xcoord,Ycoord;public:void SetX(float x)Xcoord=x;/初始化初始化 void SetY(floaty)Ycoord=y;/初始化初始化 float GetX(void)return Xcoord;float GetY(void)return Ycoord;;point p1;point*p2=new point;10例:例:mai
6、n()print(void)cuberoot(float x)add(int a,int b)属性说明属性说明 类型类型 函数名函数名(参数表参数表);参数表参数表空空/void/,例:例:add(int,int)swap(float&,float&)/引用方式引用方式函数原型中的参数表可忽略参数名函数原型中的参数表可忽略参数名11程序中某函数的调用语句出现在该函数的定程序中某函数的调用语句出现在该函数的定 义前,必须在调用语句之前列出函数原型;义前,必须在调用语句之前列出函数原型;函数原型的使用函数原型的使用/program5_1.cpp#include#includefloat cuber
7、oot(float);void main(void)类定义中,较大的函数成员定义移到类说明类定义中,较大的函数成员定义移到类说明 外,该函数的原型列于类说明之中。外,该函数的原型列于类说明之中。12例:例:class point /point:平面上一点平面上一点private:float Xcoord,Ycoord;public:void SetX(float x)Xcoord=x;/初始化初始化 void SetY(floaty)Ycoord=y;/初始化初始化 floatGetX(void)return Xcoord;floatGetY(void)return Ycoord;;13例:例
8、:class Clock /时钟类的定义时钟类的定义 public:/外部接口,公有成员函数外部接口,公有成员函数 /函数原型函数原型 void SetTime(int NewH=0,int NewM=0,int NewS=0);private:/私有数据成员私有数据成员 int Hour,Minute,Second;void Clock:SetTime(int NewH,int NewM,int NewS)Hour=NewH;Minute=NewM;Second=NewS;14函数定义包括函数体函数定义包括函数体1.1.函数说明函数说明函数定义函数定义属性说明属性说明 类型类型 函数名函数名
9、(参数表参数表)函数体函数体与函数原型一致与函数原型一致不可省略不可省略参数名参数名复合语句复合语句函数定义与函数原型的主要区别函数定义与函数原型的主要区别15例:例:class Clock /时钟类的定义时钟类的定义 public:/外部接口,公有成员函数外部接口,公有成员函数 void SetTime(int NewH=0,int NewM=0,int NewS=0);/函数原型函数原型 private:/私有数据成员私有数据成员 int Hour,Minute,Second;/函数定义函数定义void Clock:SetTime(int NewH,int NewM,int NewS)Ho
10、ur=NewH;Minute=NewM;Second=NewS;/函数体函数体 162.2.函数调用函数调用 函数调用的两要素函数调用的两要素-已定义函数的实际运行已定义函数的实际运行函数名函数名实参表实参表例:例:/program5_1.cpp函数的调用实施过程函数的调用实施过程 xr=cuberoot(-q/2+a)+cuberoot(-q/2-a);(1)搜索搜索同名函数同名函数定义;定义;/函数重载函数重载(2)核对实参的核对实参的参数个数,类型,顺序参数个数,类型,顺序,判定,判定 是否与函数定义中的形参表一致;是否与函数定义中的形参表一致;例:例:print(void)17/计算计
11、算float cuberoot(float x)float root,croot;const float eps=1e-6;croot=x;do root=croot;croot=(2*root+x/(root*root)/3;while(abs(croot-root)eps);return(croot);(3)根据参数类型根据参数类型(值值/引用引用参参 数数)进行值参数的值传递进行值参数的值传递/引用参数的换名;引用参数的换名;(4)运行函数体代码;运行函数体代码;(5)返回调用点及函数值。返回调用点及函数值。18(1)把运行控制从函数体返回到函数调用点;把运行控制从函数体返回到函数调用点
12、;(2)返回数据值。返回数据值。3.3.函数的返回函数的返回函数的返回完成的任务函数的返回完成的任务例:例:void main(void).;xr=cuberoot(-q/2+a)+cuberoot(-q/2-a);float cuberoot(float x).return(croot);19例:例:void print()cout“HelloWorld!”;void show()cout1个,以结构个,以结构/类,数组类,数组/对对象象指针类型方式实现指针类型方式实现例:例:int add(int a,int b);/返回返回1个值个值 21例:例:#includeclass comple
13、x /复数类声明复数类声明public:/外部接口外部接口 complex(double r=0.0,double i=0.0)real=r;imag=i;/构造函数构造函数 complex operator+(complex c2);/运算符运算符+重载成员函数重载成员函数 private:/私有数据成员私有数据成员double real;/复数实部复数实部double imag;/复数虚部复数虚部 ;complex complex:operator+(complex c2)return complex(real+c2.real,imag+c2.imag);22例:例:#include in
14、t&maxRef(int&x,int&y)/系统不生成返回值的副本系统不生成返回值的副本if(xy)return x;return y;void main()int a,b;coutab;coutmaxRef(a,b)endl;返回引用类型返回引用类型23例:例:void print(void);int getx();4.4.函数的参数函数的参数无参函数无参函数-void/空:无参空:无参1/多个参数多个参数例:例:/对对n元元int型数组型数组array排序排序 void sort(int n,char*array);/求求3个实数个实数a,b,c中最大者中最大者 float max(fla
15、ot a,float b,float c);241/多个参数多个参数定义中注意参数表的组成。不同的函数根据定义中注意参数表的组成。不同的函数根据函数名和参数表来区分,只有二者完全一致函数名和参数表来区分,只有二者完全一致才是同一函数。才是同一函数。P125例:函数重载例:函数重载 int abs(int n)return(n0?-n:n);float abs(float f)if(f0)f=-f;return f;double abs(double d)if(d0)return-d;return d;25不定个数参数不定个数参数-参数个数是变化的参数个数是变化的例例:设计电话计费函数,为了计算
16、通话费,不同设计电话计费函数,为了计算通话费,不同 的通话类型的通话类型(市话,长途,数据与通讯,市话,长途,数据与通讯,BP 机等机等)有不同数目的参数。有不同数目的参数。26不定个数参数不定个数参数处理参数个数不定的途径处理参数个数不定的途径例:例:void sort(int n,float*a);例:例:int f(int a,int b)return a+b*b;int f(int a,int b,int)return a*a+b;f(x,y)调用调用f(int a,int b)f(x,y,0)f(int a,int b,int)有的有的C+版本版本(VC6.0)提供库函数,支持提供库
17、函数,支持void abc(int i,);为了区分函数,允许参数表中包含无名参数为了区分函数,允许参数表中包含无名参数27C+允许为函数定义可缺省参数允许为函数定义可缺省参数处理参数个数不定的途径处理参数个数不定的途径例:例:int sqrsum(int a,int b,int c=0)/c:可缺省参数可缺省参数 return a*a+b*b+c*c;合法的调用方式合法的调用方式:sqrsum(x,y,z);/x,y,z:int型型,c=z sqrsum(x+y,x-y);sqrsum(x,y);参数表中可有任意多个参数为可缺省参数,所参数表中可有任意多个参数为可缺省参数,所有可缺省参数必须
18、列后。调用该函数时,不允有可缺省参数必须列后。调用该函数时,不允许部分缺省许部分缺省:省去全部缺省参数省去全部缺省参数/一个也不省。一个也不省。28例:例:int sqrsum(int a,int b,int c=0,int d=1)/c,d:可缺省参数可缺省参数 return a*a+b*b+c*c+d;调用方式调用方式:sqrsum(x,y,z);/,部分缺省,部分缺省 sqrsum(x+y,x-y);/,全部缺省,全部缺省 sqrsum(x,y,m,n);/,全部不缺省,全部不缺省295.5.值调用与引用调用值调用与引用调用赋值调用方式赋值调用方式赋值形参:函数定义的参数中,除了说明为赋
19、值形参:函数定义的参数中,除了说明为 引用引用(&)的参数外,其余类型的形的参数外,其余类型的形 参都属于赋值形参。赋值形参在参都属于赋值形参。赋值形参在 函数的每次调用时,必须为每个函数的每次调用时,必须为每个 赋值形参创建新的参数变量。赋值形参创建新的参数变量。函数调用时,检查函数名及参数表,为值函数调用时,检查函数名及参数表,为值参分配内存,计算对应的参分配内存,计算对应的实参表达式实参表达式,把计算,把计算的值赋给刚创建的参数变量,运行函数体。的值赋给刚创建的参数变量,运行函数体。30实参表达式:函数调用语句中与赋值形参对应实参表达式:函数调用语句中与赋值形参对应 的实参:指定类型的常
20、量的实参:指定类型的常量/变量变量/表表 达式。函数调用时,计算该表达达式。函数调用时,计算该表达 式的值,作为初值赋给刚为赋值式的值,作为初值赋给刚为赋值 形参创建的参数变量。形参创建的参数变量。赋值调用方式赋值调用方式为赋值形参创建的变量局限于函数体的局部为赋值形参创建的变量局限于函数体的局部变量,作为该形参的实例,一旦运行完毕,变量,作为该形参的实例,一旦运行完毕,撤消该参数变量。撤消该参数变量。31例:定义函数;例:定义函数;int multiple3(int n)/n:赋值形参赋值形参 n=n*3;return n;调用函数调用函数multiple3 3次:次:int n=5;/n:
21、变量变量 coutmultiple3(2)multiple3(n)multiple3(3*n)nendl;/表达式表达式 6 15 45 5执行结果执行结果32实参表达式使用只计算值的表达式实参表达式使用只计算值的表达式实参表达式实参表达式例:例:3*n,x+y,&x,multiple3(n)对可能改变变量值的表达式,注意对可能改变变量值的表达式,注意:当当1个函数个函数 有多个赋值形参时,值传递过程中,多个实参有多个赋值形参时,值传递过程中,多个实参 表达式计算的次序。表达式计算的次序。例:例:n+,m=s+m*3 realpara(n+,n-);33例:例:void swap(int&a,
22、int&b)/a,b:引用形参引用形参 int temp=a;a=b;b=temp;引用调用方式引用调用方式引用形参:函数定义的参数表中,引用形参:函数定义的参数表中,&参数名参数名函数原型:函数原型:void swap(int&a,int&b);或或void swap(int&,int&);34(1)函数的调用语句中对应于引用形参的实参必须是函数的调用语句中对应于引用形参的实参必须是同类型的变量,非变量的表达式则不允许;同类型的变量,非变量的表达式则不允许;(2)参数传递的内容:参数传递的内容:地址;地址;(3)函数体的运行中,引用形参起函数体的运行中,引用形参起“换名换名”作用;作用;(4
23、)函数体运行结束,控制转回调用点时,该引用形函数体运行结束,控制转回调用点时,该引用形参与实参变量的对应关系终止。但调用过程中对参与实参变量的对应关系终止。但调用过程中对该实参变量的处理和操作的该实参变量的处理和操作的结果结果,保留下来。,保留下来。引用形参不同于赋值形参的参数传递机制的要点引用形参不同于赋值形参的参数传递机制的要点35例:例:void swap(int&a,int&b)/a,b:引用形参引用形参 int temp=a;a=b;b=temp;调用:调用:swap(&m,&n);/swap(&(m+2),&(n+3);/36例:例:void swap(int&a,int&b)/a
24、,b:引用形参引用形参 int temp=a;a=b;b=temp;int x=5,y=3,z=7;swap(&x,&y);/结果结果x=3,y=5 swap(&y,&z);/结果结果x=5,y=7,z=353xyab37yzab5temp733temp3537例:指针例:指针 void swap(int*a,int*b)int temp=*a;*a=*b;*b=temp;int x=5,y=3;swap(&x,&y);/结果结果x=3,y=5 53xy&x&yab35xy&x&yab5temp5temp38引用调用,表面上与利用指针形参的赋值调引用调用,表面上与利用指针形参的赋值调用效果相同
25、,实际上优于指针用效果相同,实际上优于指针:不需要像指针不需要像指针参数那样通过间址访问。参数那样通过间址访问。函数采用引用参数的情形函数采用引用参数的情形改变某些变量的值;改变某些变量的值;占内存较多的参数占内存较多的参数(数组,对象数组,对象)。39int a10=0;int b10=1;int a10=0,1,2,3,4,5,6,7,8,9;int a10;a10=0,1,2,3,4,5,6,7,8,9;/40char a23=a,bb;strcpy(a0,a1);couta0;416.6.函数的嵌套与递归函数的嵌套与递归函数嵌套函数嵌套函数的函数体中包含函数的函数体中包含1/多个函数调
26、用语句多个函数调用语句嵌套:函数嵌套:函数A调用函数调用函数B。函数。函数B的定义的定义/原型必原型必 须出现在函数须出现在函数A的定义语句之前。的定义语句之前。函数函数A调用函数调用函数B:调用:调用A的过程中,调的过程中,调 用用B;执行结束返回到;执行结束返回到A的函数体中。的函数体中。42例:例:void main()fa();void fa()fb();嵌套用嵌套用stack管理,管理,调用层次调用层次时空开销时空开销43函数函数的递归的递归函数其函数体中直函数其函数体中直/间接地自己调用自己间接地自己调用自己例:间接递归例:间接递归 A调用函数调用函数B,函数,函数B又调用函数又调
27、用函数A例:例:float fac(int n)/n!float f=(n2)?1:n*fac(n-1);return f 4452 49 80 36 1449 49 80 36 14例:快速排序算法例:快速排序算法 int partition(int i,int j,float ai)int m=i;float c=ai;for(int k=i+1;kj;k+)if(akf)int m=patition(f,l,a);Qsort(f,m,a);Qsort(m,l,a);46(1)直直/间接递归必须保证在有限次调用后结束;间接递归必须保证在有限次调用后结束;(2)函数调用时系统付出时空间代价,
28、在机能函数调用时系统付出时空间代价,在机能 相同的情形下,非递归程序效率较高。相同的情形下,非递归程序效率较高。477.7.内联函数内联函数C+程序中符合条件的函数程序中符合条件的函数函数说明前:函数说明前:inline的函数;的函数;类内定义的函数成员。类内定义的函数成员。inline 类型类型 函数名(形式参数表);函数名(形式参数表);例:例:class point float Xcoord;public:void SetX(float x)Xcoord=x;;48编译过程中,编译过程中,inline函数的代码插入到该函数函数的代码插入到该函数 的各调用点,使程序执行中,每次该函数调的各
29、调用点,使程序执行中,每次该函数调 用时不需控制转移,但该函数代码可能有多用时不需控制转移,但该函数代码可能有多 个拷贝在目标程序中;个拷贝在目标程序中;把函数体短小而频繁调用的函数说明为把函数体短小而频繁调用的函数说明为inline 函数函数;编译预处理的宏定义方式,类似于编译预处理的宏定义方式,类似于inline函数函数 的功能。的功能。inline函数的方式更方便和可靠。函数的方式更方便和可靠。7.7.内联函数内联函数49使用内联函数注意使用内联函数注意内联函数体内不能有循环语句和内联函数体内不能有循环语句和 switch语句;语句;若已在函数原型中指定若已在函数原型中指定inline,
30、函,函 数定义时不能重复给出;数定义时不能重复给出;递归函数不能被定义成递归函数不能被定义成“内联内联”函数。函数。50例:例:#include#include inline int isnumber(char);void main()char c;int n;n=0;while(c=getchar()!=n)if(isnumber(c)n+;int isnumber(char ch)return(ch=0&ch=9)?1:0;515.3 函数与运算符的重载函数与运算符的重载1.1.重载重载-同名不同义,不同情况下表现出不同同名不同义,不同情况下表现出不同“行为行为”,面向对象系统的面向对象系
31、统的3 3大特性之一的大特性之一的多态性多态性通过通过重重 载载实现实现函数重载:多个函数同名,但执行的操作和函数重载:多个函数同名,但执行的操作和 操作对象不同操作对象不同操作符重载:一个运算符,可进行多种不同操作符重载:一个运算符,可进行多种不同 含义的解释,进行不同操作含义的解释,进行不同操作 重载重载52例:比较大小:例:比较大小:2 2个整数比较、个整数比较、2 2个浮点数比个浮点数比 较、较、.在在C+C+中必须逐个定义不同名的多个函数中必须逐个定义不同名的多个函数 目标:系统自动判断,用户只要记住函数目标:系统自动判断,用户只要记住函数 名即可名即可 重载:写多个同名函数,由系统
32、根据操作重载:写多个同名函数,由系统根据操作 数自动判断调用哪个函数数自动判断调用哪个函数532.2.函数(名)重载函数(名)重载-为了方便程序员的使用,为了方便程序员的使用,多个不同的函数采多个不同的函数采 用同一名字用同一名字例:例:int abs(int n)return(n0?-n:n);float abs(float f)if(f0)f=-f;return f;double abs(double d)if(d0)return-d;return d;不同的数据类型求和,数据的差别很大不同的数据类型求和,数据的差别很大(整数整数/向量向量/矩阵矩阵),求和操作差别也大,但完成不,求和操作
33、差别也大,但完成不同求和操作的函数可以取相同名字同求和操作的函数可以取相同名字54例:例:int abs(int n)return(n0?-n:n);float abs(float f)if(f=2个个 同名函数与之匹配;找不到与之同名函数与之匹配;找不到与之 匹配的函数定义。匹配的函数定义。59定义同名函数时注意定义同名函数时注意(4)包含可缺省参数时,可能造成二义性包含可缺省参数时,可能造成二义性例:例:int sum(int a,int b,int c=0);int sum(int a,int b);调用:调用:sum(5,3);/二义性二义性a.寻找寻找1个完全匹配,找到就调用个完全匹
34、配,找到就调用 b.通过内部转换寻找通过内部转换寻找1个匹配,找到就调用个匹配,找到就调用 c.通过用户自己定义的转换寻找通过用户自己定义的转换寻找1个匹配,找到个匹配,找到 就调用就调用匹配重载函数的顺序匹配重载函数的顺序 60无准确匹配的函数定义时的处理方式无准确匹配的函数定义时的处理方式(1)数组名数组名-指针变量,函数名指针变量,函数名-函数指针,某类函数指针,某类 型变量型变量-const常量的转换,实现匹配常量的转换,实现匹配?(2)实参类型实参类型:低低高高(字长字长:短短长长)进行基本类型进行基本类型 -派生类型的转换,可匹配派生类型的转换,可匹配?(3)有无可变个数参数的函数
35、,如有把它归为该有无可变个数参数的函数,如有把它归为该 函数。函数。上述尝试性处理后可能出现仍无匹配上述尝试性处理后可能出现仍无匹配/匹配不唯匹配不唯 一,可能输出出错信息一,可能输出出错信息/错误运行。错误运行。定义同名函数时注意定义同名函数时注意61(4)同名函数应具有相同的功能同名函数应具有相同的功能 定义同名函数时注意定义同名函数时注意例:例:#include#include int add(int add(intint x,x,intint y)y)coutint,int:;return x+y;coutint,int:;return x+y;double add(double ad
36、d(doubledouble x,x,doubledouble y)y)coutdouble,double:;return x+y;coutdouble,double:;return x+y;int add(int add(intint x,x,doubledouble y)y)coutint,double:;return int(x+y);coutint,double:;return int(x+y);double add(double add(doubledouble x,x,intint y)y)coutdouble,int:;return x+y;coutdouble,int:;ret
37、urn x+y;62void main()void main()coutadd(99,88)endl;coutadd(99,88)endl;coutadd(99.9,88.8)endl;coutadd(99.9,88.8)endl;coutadd(99,88.8)endl;coutadd(99,88.8)endl;coutadd(99.9,88)endl;coutadd(99.9,88)endl;633.3.运算符重载的需要性运算符重载的需要性问题的提出:问题的提出:C+C+中,定义一个类就产生一个新类型,类的对中,定义一个类就产生一个新类型,类的对象和变量一样可以作为参数传递象和变量一样可以
38、作为参数传递/函数的返回类型函数的返回类型 希望某些运算符能对整个对象操作,而不是希望某些运算符能对整个对象操作,而不是C C的简单操作的简单操作 例:例:+运算符能够实现运算符能够实现2 2个对象间的加个对象间的加 把某些事交给系统去做,用户只要知道相加就可把某些事交给系统去做,用户只要知道相加就可 提出运算符重载,扩充运算符的功能。即:对运算符进提出运算符重载,扩充运算符的功能。即:对运算符进 行重载定义,然后使用,由系统自动判断采用哪个具体行重载定义,然后使用,由系统自动判断采用哪个具体 的运算符的运算符 C+C+语言的可扩充性语言的可扩充性64例:类例:类A A的对象的对象a1a1、a
39、2a2、a3a3,希望:,希望:a3=a1+a2a3=a1+a2;分别把对象分别把对象a1a1和和a2a2的各个数据成员值对应相加,的各个数据成员值对应相加,然后赋给对象然后赋给对象a3 a3 实现途径:对运算符进行重载实现途径:对运算符进行重载654.4.可重载运算符可重载运算符P127限定符限定符 ,:条件运算符条件运算符?:取长度运算符取长度运算符sizeof不可重载的运算符不可重载的运算符可重载的运算符中的情况可重载的运算符中的情况1)算术算术/逻辑逻辑/位运算符和关系运算符中的位运算符和关系运算符中的,=,与基本数据类型有关,通过重载,与基本数据类型有关,通过重载,使之用于用户定义的
40、数据类型;使之用于用户定义的数据类型;66可重载的运算符中的情况可重载的运算符中的情况2)赋值运算符赋值运算符=,关系运算符,关系运算符=,!=,指针运算,指针运算 符符&和和*,下标运算符,下标运算符,涉及的数据类型按,涉及的数据类型按 C+规定,不限于基本数值类型,规定,不限于基本数值类型,“自动自动”重载;重载;3)+/-可作为前可作为前/后缀:后缀:后缀后缀+的重载函数的原型参数表中增加的重载函数的原型参数表中增加int型的型的 无名参数。无名参数。前前缀缀+operator+()/作为类成员作为类成员 operator+()/作为类外函数作为类外函数后后缀缀+operator+(in
41、t)/作为类成员作为类成员 operator+(,int)/作为类外函数作为类外函数67前前缀缀+a或或a.operator+()operator+(a)后后缀缀+a+或或a.operator+(0)operator+(a,0)调用调用:前前缀缀+operator+()/作为类成员作为类成员 operator+()/作为类外函数作为类外函数后后缀缀+operator+(int)/作为类成员作为类成员 operator+(,int)/作为类外函数作为类外函数68例:例:#include#include class Increaseclass Increasepublic:public:Incre
42、ase(int x):value(x)Increase(int x):value(x)friend Increase&operator+(Increase&);/friend Increase&operator+(Increase&);/前增量前增量 friend Increase operator+(Increase&friend Increase operator+(Increase&,int);/int);/后增量后增量 void display()cout the value is value endl;void display()cout the value is value end
43、l;private:private:int value;int value;Increase&Increase:operator+(Increase&a)Increase&Increase:operator+(Increase&a)a.value+;/a.value+;/先增量先增量 return a;/return a;/再返回原对象再返回原对象 Increase Increase:operator+(Increase&a,int)Increase Increase:operator+(Increase&a,int)Increase temp(a);/Increase temp(a);/通过
44、拷贝构造函数保存原有对象值通过拷贝构造函数保存原有对象值 a.value+;/a.value+;/原有对象增量修改原有对象增量修改 return temp;/return temp;/返回原有对象值返回原有对象值 695.5.运算符重载函数的定义运算符重载函数的定义 operator函数名函数名例:前缀例:前缀 operator+()operator+()70#include class Numberint x;public:Number()x=0;Number(int i)x=i;void disp()coutx=xendl;void operator+()x+;/前置运算符前置运算符voi
45、d operator+(int)x+=2;/后置运算符后置运算符;71void main()Number obj(5);obj.disp();+obj;/调用前置运算符调用前置运算符 obj.disp();obj+;/调用后置运算符调用后置运算符 obj.disp();72#include class vectorint x,y;public:vector();vector(int i,int j)x=i;y=j;void disp()cout(x,y)endl;void operator+=(vector D)x+=D.x;y+=D.y;void operator-=(vector D)x-
46、=D.x;y-=D.y;73void main()vector A(1,2),B(4,2);coutA:;A.disp();coutB:;B.disp();A+=B;coutA+=B:;A.disp();A-=B;coutA-=B:;A.disp();74例:例:#include enum newboolFalse,True;newbool operator+(newbool a,newbool b)if(a=False)&(b=False)return False;return True;newbool operator*(newbool a,newbool b)if(a=True)&(b=
47、True)return True;return False;newbool operator-(newbool a)if(a=False)return True;return False;75main()newbool b1=True,b2=False,b3=True;b1=b1+b2;coutb1endl;b1=operator+(b1,b2);/b1=b1+b2;coutb1endl;b1=operator-(b3);coutb1endl;b1=(b1+b3)*False;coutb1endl;76输出结果输出结果77运算符重载函数的调用运算符重载函数的调用(1)与原运算符相同的调用方式与
48、原运算符相同的调用方式(2)一般函数调用方式一般函数调用方式 例:例:b1=b1+b2;例:例:b1=operator+(b1,b2);785.4 程序实例程序实例1.1.“三色冰激凌三色冰激凌”程序程序 28种颜色的原料,组合成多少种三色种颜色的原料,组合成多少种三色冰激淋冰激淋:1)P283=28*27*26种;种;2)C283=P283/3!种。种。元素数元素数:28,选择数,选择数:3。79/program 5_2.cpp#include long factorial(int number);void main(void)int i,selections,elements;coutse
49、lections;/3 coutelements;/28 double answer=elements;for(i=1;iselections;i+)/P283=28*27*26 answer*=-elements;coutA(elements+selections-1,selections)=;coutanswerendl;80answer/=factorial(selections);/C283=P283/3!coutC(elements+selections-1,selections)=;coutanswer1)value*=number-;return value;81long fac
50、torial(int number)if(number=1)return 1;else return number*factorial(number-1);/n!的递归算法的递归算法/n!=1 n1fact(3)fact(2)*3fact(1)*2=182运行结果运行结果832.2.Hanoi塔问题塔问题 有有3个立柱个立柱A,B,C,A柱上穿有大小柱上穿有大小不等的圆盘不等的圆盘64个,较大的圆盘在下,较小个,较大的圆盘在下,较小者在上。要求借助于者在上。要求借助于B柱把柱把A柱上的柱上的64个圆个圆盘移到盘移到C柱,规则:柱,规则:(1)每次只能把一个柱上最上面的圆盘移至每次只能把一个柱上