第11章 友元与运算符重载(3)

2019-03-09 14:35

第11章 友元与运算符重载 ·285·

Complex(float r=0,float i=0) {Real=r;Image=i;}

void Show(int i)

{ cout<<\

friend Complex operator + (Complex & ,Complex &); //“+”重载函数为友元函数 friend Complex operator-(Complex &, Complex &); //“-”重载函数为友元函数 friend Complex operator + (Complex &,float); };

Complex operator + (Complex &c1, Complex &c2) { Complex t;

t.Real=c1.Real+c2.Real; t.Image=c1.Image+c2.Image; return t; }

Complex operator-(Complex &c1, Complex &c2) { Complex t;

t.Real=c1.Real-c2.Real; t.Image=c1.Image-c2.Image; return t; }

Complex operator + (Complex &c,float s) { Complex t;

t.Real=c.Real+s; t.Image=c.Image; return t; }

void main(void)

{ Complex c1(25,50),c2(100,200),c3,c4; c1.Show(1); c2.Show(2); c3=c1+c2; //c3=(25+50i)+(100+200i)=125+250i c3.Show(3); c4=c2-c1; //c4=(100+200i)-(25+50i)=75+150i c4.Show(4); c1=c1+200; c1.Show(1); }

程序执行后输出:

c1=25+50i

//c1=25+50i+200=225+50i

第11章 友元与运算符重载

c2=100+200i c3=125+250i c4=75+150i c1=225+50i

·286·

在此例中,“+”与“-”运算符的重载函数均为普通函数,并在复数类中说明成复数类的友元函数。因此在三个运算符重载函数中可以使用复数类对象的私有数据成员,即复数的实部与虚部参加相应的算术运算。

从主函数可以看出,用成员函数与友元函数为运算符重载函数,就运算符的使用来讲是一样,但编译器处理方法是不同的,例如对表达式:c3=c1+c2;的处理是,先将c1+c2变换为对友元函数的调用:operator+(c1,c2);再将函数返回结果即两复数的和t赋给复数c3,因此表达式c3=c1+c2; 实际执行了c3= operator+(c1,c2) 的函数调用及赋值工作。

友元函数与成员函数作为二元运算符重载函数的另一个区别是:

当重载函数为成员函数时,二元运算符的左操作数为调用重载函数的对象。右操作数为实参。

当重载函数为友元函数时,二元运算符的左操作数为调用重载函数的第一个实参。右操作数为第二个实参。

11.2.3 一元运算符的重载

所谓一元运算符是只有一个操作数的运算符,如自加运算符“++”,自减运算符“--”等等。与二元运算符的重载类似,一元运算符重载函数也分为类的成员函数与友元函数两类。

1.一元运算符重载函数为类的成员函数

一元运算符重载函数为类的成员函数的格式: <类型><类名>::operator <一元运算符>(形参) { 函数体}

现对比较典型的一元运算符“++”、“--”进行讨论。对于一元运算符“++”、“--”存在前置与后置问题,因此定义函数时会有所区别。

(1)“++”为前置运算符时,函数格式为: <类型><类名>::operator ++( ) {函数体} (2)“++”为后置运算符时,函数格式为 <类型><类名>::operator ++( int ) {函数体}

由于是用运算符重载函数来实现“++”运算,所以这里的“++”是广义上的增量运算符。在后置运算符重载函数中,形参int仅用作区分前置还是后置,并无实际意义,可以给一个变量名,也可不给出变量名。

【例11.7】定义一个描述时间计数器的类,其三个数据成员分别用于存放时、分和秒。用成员函数重载“++”运算符,实现计数器对象的加1运算。

# include

第11章 友元与运算符重载

class 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 ++( ); //定义“前置++”运算符重载成员函数 TCount operator ++( int ); //定义“后置++”运算符重载成员函数 void Show(int i ) //定义显示时:分:秒的成员函数

·287·

{cout<<\};

TCount TCount ::operator ++ () { Second++;

if (Second==60) { Second=0; t1=*this t1=*this Minute++;

Hour = 10 Hour = 10 this this if (Minute==60)

Minute=25 Minute=25 { Minute=0;

Second=50 Second=51 Hour++;

if (Hour==24) (a) t1自加前的内容 (b) t1自加后的内容

{ Hour=0;} 图11.2 系统为t1分配的内存空间及this指针 } }

return *this; }

TCount TCount::operator++ (int ) { TCount temp=*this;

temp=*this t1=*this Second++;

if (Second==60) Hour = 10 Hour = 10 this { Second=0; Minute=25 Minute=25 Minute++; Second=51 Second=52 if (Minute==60) 临时对象temp 自加后的内容 (a) (b) t1 { Minute=0;

图11.3 t1对象、this指针与临时对象temp Hour++;

if (Hour==24) { Hour=0;} } }

return temp;

第11章 友元与运算符重载

}

void 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++;

·288·

//先加后用,即:先将t1自加,然后将t1赋给t2

//先用后加,即:先将t1赋给t3,然后将t1自加

t1.Show(1); t3.Show(3); }

程序执行后输出:

t1=10:25:50 t1=10:25:51 t2=10:25:51 t1=10:25:52 t3=10:25:51

说明:

(1)TCount为描述时间计数器的类,其数据成员Hour、Minute、Second分别代表时、分、秒。在主函数中定义时间计数器对象t1、t2、t3,t1的初始值为10时25分50秒。

(2)对对象的自加操作“++”,是对时间计数器的秒加1运算。当秒计满60后,将其清0并对分加1。当分计满60后,将其清0并对时加1。当时计满24后,将其清0。

(3)“前置++”运算符重载成员函数的说明

在主函数中执行t2=++t1语句时,先将t1自加,然后将t1赋给t2。该语句操作是通过调用“前置++”运算符重载成员函数来实现的。在执行t2=++t1语句时,编译系统将t2=++t1解释为对重载函数的调用:

t2=t1.operator ++ ();

由于重载函数为对象t1成员函数,所以函数体对Hour、Minute、Second的自加操作就是对t1的数据成员Hour、Minute、Second的自加操作,因而可完成对计数器对象t1的加1操作。

为了实现前置“++”运算,应将加1后的对象值t1作为返回值,即用return t1语句返回当前对象t1值。但在重载函数体内并不能直接使用对象t1,因而无法使用return t1语句。这时必须使用指向当前对象t1的指针this,如图11.2所示。由于*this=t1,所以用return *this 语句可将自加后的t1值返回给调用函数,并赋给对象t2。由于将对象值t1值作为函数返回值,所以重载函数的类型应与t1的类型相同,为TCount类型。

(4)“后置++”运算符重载成员函数的说明

在主函数中执行t3=t1++语句时,先将t1赋给t3,然后将t1自加。该语句操作是通过调用“后置++”运算符重载成员函数来实现的。在执行t3=t1++语句时,编译系统将t3=t1++解释为对重载函数的调用:

第11章 友元与运算符重载 ·289·

t3=t1.operator ++ (1);

为了实现后置“++”运算,应将加1前的对象值t1作为返回值,这时应使用指向当前对象t1的指针this。在后置重载函数中先用TCount类定义一个临时对象temp,并将t1值(即*this值)赋给temp,在函数最后用return temp语句将加1前的t1值返回给函数,并赋给对象t2。如图11.3所示。

(5)用成员函数实现一元运算符的重载时,运算符的左操作数或右操作数为调用重载函数的对象。因为要用到隐含的this指针,所以运算符重载函数不能定义为静态成员函数,因为静态成员函数中没有this指针。

2.一元运算符重载函数为友元函数

重载一元运算符友元函数的一般格式为:

<类型> operator <一元运算符>(类名 &对象) {函数体} 对于“++”、“――”运算符存在前置运算与后置运算的问题,因此,运算符重载函数必须分为两类。以“++”运算符为例,用友元函数来实现“++”运算符的重载时

前置“++”运算符重载的一般格式为:<类型> operator ++ ( 类名 &); 后置“++”运算符重载的一般格式为:<类型> operator ++ ( 类名 &,int );

其中:形参为要实现“++”运算的对象,int 只是用于区分是前置还是后置运算符,并无整型数的含义。

【例11.8】用一个类来描述时间计数器,用三个数据成员分别存放时、分和秒。用友元函数重载“++”运算符,实现计数器对象的加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 operator ++(TCount &t ); //定义“前置++”运算符重载友元函数 friend TCount operator ++( TCount &t ,int ); //定义“后置++”运算符重载友元函数 void Show(int i )

{ cout<<\};

TCount operator ++ (TCount & t) { t.Second++;

if (t.Second==60) { t.Second=0; t.Minute++;


第11章 友元与运算符重载(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:2016注册咨询后续教育-城市轨道交通线网规划

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: