重载.docx
- 文档编号:27510335
- 上传时间:2023-07-02
- 格式:DOCX
- 页数:40
- 大小:23.78KB
重载.docx
《重载.docx》由会员分享,可在线阅读,更多相关《重载.docx(40页珍藏版)》请在冰豆网上搜索。
重载
重载
重载是C++的一个重要特征,它包含函数重载和操作符重载。
一、函数重载
所谓函数重载是指同一个函数名可以对应着多个函数的实现。
函数重载
允许一个过程内声明多个名称相同的函数,这些函数可以完成不同的功能,
并可以带有不同的类型、不同数目的参数及返回值。
使用函数重载可以减轻
用户的记忆负担,并使程序的结构简单、易懂。
函数重载要求编译器能够唯一地确定调用一个函数时应执行哪个函数代
码,即采用哪个函数的实现。
确定函数实现时,要求从函数参数的个数和类
型上来区分。
也就是说,函数重载时,要求函数的参数个数或参数类型不同。
例1:
两个不同参数类型的重载。
#include
#include
#include
classMy_class//声明一个类
{
public:
intplus(int,int);
doubleplus(double,double);
};
intMy_class:
:
plus(intx,inty)
{returnx+y;
}
doubleMy_class:
:
plus(doublex,doubley)
{returnx+y;
}
voidmain()
{My_classData;
cout<<"Theresultforplus(int,int)is:
"< cout<<"Theresultforplus(double,double)is: ”< } 运行结果为: Theresultforplus(int,int)is: 15 Theresultforplus(double,double)is: 15 在类My_class中对方法plus进行了重载,通过重载,使得在求两个数的和时不用再区分整数和浮点数之间的不同之处,而只需直接调用My_class的方法plus即可。 不仅在类的成员函数上可以实现重载,在构造函数上也可以实现函数的重载。 例2: 在构造函数上的重载。 #include #include voidmain() {classstud//声明一个类 {private: intnum; charname[10]; charsex;//以上3行是数据成员 public: stud()//定义构造函数,函数名与类名相同,在构造函数中给数据赋初值 {num=10010;//给数据赋初值 strcpy(name,"Wang_li"); sex='F'; }//以上3行为给数据赋初值 stud(intn,charnam[],chars) //定义构造函数,有形参,由实参将值传给形参 {num=n; strcpy(name,nam); sex=s; } voiddisplay()//定义成员函数,输出对象的数据 {cout<<"num: "< cout<<"name: "< cout<<"sex: "< }//以上3行是操作代码 }; studstud1,stud2(10011,"Zhang_fun",'m'); //在定义对象stud1、stud2时自动执行构造函数,同时给出相应实参 stud1.display(); stud2.display();//从对象外面调用display函数,分别输出两个学生的数据 } 运行结果为: num: 10010 name: Wang_li sex: F num: 10011 name: Zhang_fun sex: m 例3: 在构造函数上的重载。 #include #include classstud//声明一个类 {private: intnum; charname[10]; charsex;//以上3行是数据成员 public: stud();//对重载的构造函数作原型声明 stud(intn,charnam[],chars);//对重载的构造函数作原型声明 voiddisplay();//对成员函数display的原型声明 }; stud: : stud()//定义重载的构造函数 {num=10010; strcpy(name,"Wang_li"); sex='F'; } stud: : stud(intn,charnam[],chars) //定义构造函数,函数名与类名相同,有形参 {num=n;//给数据赋初值 strcpy(name,nam); sex=s; }//以上3行为给数据赋初值 voidstud: : display()//定义成员函数,输出对象的数据 {cout<<"num: "< cout<<"name: "< cout<<"sex: "< }//以上3行是操作代码 voidmain() {studstud1,stud2(10011,"Zhang_Fun",'m'); //在定义对象stud1、stud2时自动执行构造函数,同时给出相应实参 stud1.display(); stud2.display();//从对象外面调用display函数,分别输出两个学生的数据 } 运行结果为: num: 10010 name: Wang_li sex: F num: 10011 name: Zhang_Fun sex: m 例4: 在构造函数上的重载。 #include #include classstud//声明一个类 {private: intnum;//数据成员 public: stud();//对重载的构造函数作原型声明 stud(intn);//对重载的构造函数作原型声明 voiddisplay();//对成员函数display的原型声明 }; stud: : stud()//定义重载的构造函数 {num=10010;//给数据赋初值 } stud: : stud(intn)//定义构造函数,函数名与类名相同,有形参 {num=n;//给数据赋初值 } voidstud: : display()//定义成员函数,输出对象的数据 {cout<<"num: "< } voidmain() {studstud1,stud2(10011); //在定义对象stud1、stud2时自动执行构造函数,同时给出相应实参 stud1.display(); stud2.display();//从对象外面调用display函数 } 运行结果为: num: 10010 num: 10011 例5: 在构造函数上的重载。 #include #include classsample//声明一个类 {private: inti;//数据成员 public: sample();//对重载的构造函数作原型声明 sample(intn);//对重载的构造函数作原型声明 voiddisplay();//对成员函数display的原型声明 }; sample: : sample()//定义重载的构造函数 {i=0;//给数据赋初值 } sample: : sample(intx)//定义重载的构造函数,函数名与类名相同,有形参 {i=x;//给数据赋初值 } voidsample: : display()//定义成员函数,输出对象的数据 {cout<<"i=: "< } voidmain() {sampleA,B(5); //在定义对象A、B时自动执行构造函数,同时给出相应实参 A.display(); B.display();//从对象外面调用display函数 } 运行结果为: i=: 0 i=: 5 二、操作符(运算符)重载 操作符重载的能力增强了C++语言的可扩充性,是面向对象程序设计的重要 特征。 对操作符的重载是将C++语言中已有的操作符赋予新的功能,但与该操作 符的本来含义不冲突,使同一个运算符作用于不同的数据进行操作运算,使用时 只需根据操作符出现的位置来判断其具体执行哪一种运算。 C++中单目运算、双目运算、物理内存管理运算符new和delete以及指针、 引用等运算操作均可以重载。 要注意的是,由于单目运算操作只能有一个参数, 因此重载++和—运算操作时,不可能区分是前置操作还是后置操作。 使用操作符重载时,必须用以下的方式来声明成员函数: 函数类型operator#(形参表) 其中,operator是关键字,#表示欲重载的操作符,函数类型指明返回值类型, 通常与类类型一致或为void型。 例6: 通过函数来实现复数相加(没有用运算符重载) #include usingnamespacestd; classComplex {public: Complex(){real=0;imag=0;} Complex(doubler,doublei){real=r;imag=i;} Complexcomplex_add(Complex&c2); voiddisplay(); private: doublereal; doubleimag; }; ComplexComplex: : complex_add(Complex&c2) {returnComplex(real+c2.real,imag+c2.imag);} voidComplex: : display() {cout<<"("< intmain() {Complexc1(3,4),c2(5,-10),c3; c3=plex_add(c2); cout<<"c1=";c1.display(); cout<<"c2=";c2.display(); cout<<"c1+c2=";c3.display(); return0; } 将两个complex类对象相加 #include classcomplex {public: doublereal; doubleimag; public: complex(doubler=0.0,doublei=0.0) {real=r;imag=i;} }; complexoperator+(complexco1,complexco2) {complextemp; temp.real=co1.real+co2.real; temp.imag=co1.imag+co2.imag; returntemp; } voidmain() {complexcom1(2.3,4.6),com2(3.6,2.8),total1,total2; total1=operator+(com1,com2);//调用运算符重载函数operator+的第一种方式 cout<<"real1="< total2=com1+com2;//调用运算符重载函数operator+的第二种方式 cout<<"real2="< } 运行结果为: real1=5.9imag1=7.4 real2=5.9imag2=7.4 可以看出,针对类complex重载了运算符“+”之后,复数加法的书写形式 变得十分简单,并且和预定义类型数据加法的书写形式一样符合人的习惯。 三、运算符重载函数的两种形式 (一)、友元运算符函数 在C++中,可以把运算符重载函数定义成某个类的友元函数,称为 友元运算符函数。 1、友元运算符函数定义的语法形式 友元运算符函数的原型在类的内部声明格式如下: classX {… friend返回类型operator运算符(形参表); … } 在类外定义友元运算符函数的格式如下: 返回类型operator运算符(形参表) { 函数体 } 其中,X是重载此运算符的类名,返回类型指定了友元运算符函数 的运算结果类型;operator是定义运算符函数的关键字;运算符既是 要重载的运算符名称,必须是C++中可重载的运算符;形参表中给出 重载运算符所需要的参数和类型;关键字friend声明这是一个友元 运算符函数。 由于友元运算符函数不是该类的成员函数,所以在类外 定义时不需要缀上类名。 友元运算符函数没有this指针,若友元运算符函数重载的是双目 运算符,则参数表中有两个操作数;若重载的是单目 运算符,则参数表中只有一个操作数。 2.双目运算符重载 当用友元函数重载双目运算符时,两个操作数都要传递给运算符函数。 在C++中,不能直接进行复数的加、减、乘、除运算,我们可以定义4个 友元运算符函数,通过重载+、-、*、/运算符来实现复数运算。 例7: #include classcomplex {private: doublereal;//复数实部 doubleimag;//复数虚部 public: complex(doubler=0.0,doublei=0.0);//构造函数 voidprint(); //用友元运算符函数重载运算符“+” friendcomplexoperator+(complexa,complexb);//用友元运算符函数重载运算符“+” friendcomplexoperator-(complexa,complexb);//用友元运算符函数重载运算符“-” friendcomplexoperator*(complexa,complexb);//用友元运算符函数重载运算符“*” friendcomplexoperator/(complexa,complexb);//用友元运算符函数重载运算符“/” }; complex: : complex(doubler,doublei) {real=r;imag=i;} complexoperator+(complexa,complexb) {complextemp; temp.real=a.real+b.real; temp.imag=a.imag+b.imag; returntemp; } complexoperator-(complexa,complexb) {complextemp; temp.real=a.real-b.real; temp.imag=a.imag-b.imag; returntemp; } complexoperator*(complexa,complexb) {complextemp; temp.real=a.real*b.real-a.imag*b.imag; temp.imag=a.real*b.imag+a.imag*b.real; returntemp; } complexoperator/(complexa,complexb) {complextemp; doublet; t=1/(b.real*b.real+b.imag*b.imag); temp.real=(a.real*b.real+a.imag*b.imag)*t; temp.imag=(b.real*a.imag-a.real*b.imag)*t; returntemp; } voidcomplex: : print() {cout< if(imag>0)cout<<"+"; if(imag! =0)cout< } intmain() {complexA1(2.3,4.6),A2(3.6,2.8),A3,A4,A5,A6; A3=A1+A2; A4=A1-A2; A5=A1*A2; A6=A1/A2; A1.print(); A2.print(); A3.print(); A4.print(); A5.print(); A6.print(); return0; } 运行结果为: 2.3+4.6i 3.6+2.8i 5.9+7.4i -1.3+1.8i -4.6+23i 1.01731+0.486538i 一般而言,如果在类X中采用友元函数重载双目运算符@,而aa和bb 是类X的两个对象,则以下两种函数调用方法是等价的: aa@bb;//隐式调用 operator@(aa,bb);//显式调用 有时,在函数返回的时候,可以直接用类的构造函数来生成一个临时 对象,而不对该对象进行命名,如可将上例重载运算符“+”的程序片断: complexoperator+(complexa,complexb) {complextemp; temp.real=a.real+b.real; temp.imag=a.imag+b.imag; returntemp; } 改为: complexoperator+(complexa,complexb) { returnoperator(a.real+b.real,a.imag+b.imag); } 其中语句: returnoperator(a.real+b.real,a.imag+b.imag); 中就调用了类complex的构造函数生成了一个无名的临时对象。 它的含义是 “创建一个临时对象并返回它”。 这两种方法的执行效率是完全不同的。 上例中执行函数operator+()的过程是 这样的: 创建一个局部对象temp(这时会调用构造函数),执行return语句时会 调用拷贝构造函数,把temp的值拷贝到主调函数中的一个无名临时对象中。 当函 数operator+()结束时,会调用析构函数析构对象temp,然后,temp消亡。 新方法 的效率高的多,是直接将一个无名临时对象创建到主调函数中。 3.单目运算符重载 例8: 用友元函数重载单目运算符“-” #include classOper//声明一个类 {private: inta,b; public: Oper(intx=0,inty=0) {a=x;b=y;} friendOperoperator-(Operobj);//声明重载单目运算符"-" voidprint(); }; Operoperator-(Operobj)//定义重载单目运算符"-" { obj.a=-obj.a; obj.b=-obj.b; returnobj; } voidOper: : print()
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 重载