第11章 友元与运算符重载
·290·
if (t.Minute==60) { t.Minute=0; t.Hour++;
if (t.Hour==24) { t.Hour=0;} } }
return t; }
TCount operator++ (TCount & t,int ) { TCount temp=t; t.Second++;
if (t.Second==60) { t.Second=0; t.Minute++;
if (t.Minute==60) { t.Minute=0; t.Hour++;
if (t.Hour==24) { t.Hour=0;} } }
return temp; }
void main(void)
{ TCount t1(10,25,50),t2,t3; t1.Show(1); t2=++t1; t1.Show(1); t2.Show(2); t3=t1++;
t1.Show(1); t3.Show(3); }
程序执行后输出:
t1=10:25:50 t1=10:25:51 t2=10:25:51 t1=10:25:52
//t1=10:25:50 //先加后用
//先用后加
第11章 友元与运算符重载
t3=10:25:51
·291·
说明:
(1)对“前置++”运算符重载友元函数的说明
在主函数中t2=++t1语句的含义是:先将t1自加,然后将自加后的t1值赋给t2。该语句操作是通过调用“前置++”运算符重载友元函数来实现的。在执行t2=++t1语句时,编译系统将t2=++t1解释为对重载函数的调用:
t2=operator ++ (t1);
为了实现对t1的自加操作,重载函数的形参t必须与实参t1占用同一内存空间,使对形参t的自加操作变为对实参t1的自加操作。为此,形参t必须定义为时间计数器类TCount的引用,即:TCount & t。此外,为了能将t自加的结果通过函数值返回给t2,重载函数的返回类型必须与形参t相同,即为时间计数器类TCount的引用。故“前置++”运算符重载友元函数定义为:
TCount & operator ++ (TCount & t) //函数返回类型与形参t相同,均为TCount &
{ t.Second++; ?
return t; }
当系统自动调用“前置++”运算符重载友元函数时,对形参t与实参t1自加后,用return t语句将自加的结果通过函数返回并赋给t2。从而实现对t1先加后赋值给t2的操作。
(2)对“后置++”运算符重载友元函数的说明
在主函数中t3=t1++语句的含义是:先将t1当前值赋给t3,然后再对t1自加。该语句操作是通过调用“后置++”运算符重载友元函数来实现的。在执行t3=t1++语句时,编译系统将t3=t1++解释为对重载函数的调用:
t3=operator ++ (t1,1);
为了实现对t1的自加操作,重载函数的形参t必须与实参t1占用同一内存空间,使对形参t的自加操作变为对实参t1的自加操作。为此,形参t必须定义为时间计数器类TCount的引用,即:TCount & t。此外,为了能将t自加前的结果通过函数值返回给t3,在重载函数内第一条语句定义了TCount 类的临时对象temp,并将自加前t值赋给temp,在函数的最后用return temp语句返回自加前的t值。重载函数的返回类型必须与对象temp相同,即为TCount类型。故“后置++”运算符重载友元函数定义为:
TCount operator ++ (TCount & t,int) //函数返回类型与temp相同,均为TCount类型
{ TCount temp=t; t.Second++; ?
return temp; }
当系统自动调用“后置++”运算符重载友元函数时,对形参t与实参t1自加后,用return temp语句将自加前的结果通过函数返回并赋给t3。从而实现先将t1赋给t3后将t1自加的操作。
第11章 友元与运算符重载 ·292·
【例11.9】用一个类来描述人民币币值,用两个数据成员分别存放元和分。重载“++”运算符,用运算符重载成员函数实现对象的加1运算。
# include
float Dollars,Cents; public:
Money() { Dollars=Cents=0;}
Money(float,float); Money(float); Money operator ++( ); Money operator ++( int ); float GetAmount(float & n)
//定义数据成员元与分 //定义默认的构造函数
//定义双参数构造函数 //定义单参数构造函数
//定义前置“++”运算符重载成员函数 //定义后置“++”运算符重载成员函数 //通过形参n返回元,通过函数返回分
{ n=Dollars; return Cents; }
~ Money( ) { }; //缺省的析构函数
void Show( ) //定义显示元与分的成员函数 { cout< }; Money::Money(float n) //初始值n中整数部分为元,小数部分为分 { float Frac,num; Frac=modff(n,&num); // modff(n,&num)将实数n分为解为整数与小数两部分, //返回小数值给Frac,整数值送到num单元中 Cents=Frac*100; //存分值 Dollars=num; //存元值 } Money::Money(float d,float c) { float sum,dd,cc; sum=d+c/100; cc=modff(sum,&dd); Dollars=dd; Cents=cc*100; } Money Money::operator ++ () //d以元为单位(如d=10.5元), // c以分为单位(如c=125分) //将d与c转换为以元为单位, //并存入sum(如sum=10.5+125/100=11.75) //将整数(即:元)存入dd,小数(即:分)存入cc //元存入Dollars //分存入Cents //定义前置“++”重载函数 第11章 友元与运算符重载 { Cents++; if (Cents>=100) { Dollars++; Cents=Cents-100; } return *this; ·293· //分加1 //若分大于100,则元加1,分减100 //返回自加后的人民币对象值 } Money Money::operator++ (int ) { Money temp=*this; Cents++; if (Cents>=100) //将自加前人民币对象值存入临时对象temp //分加1 //若分大于100,则元加1,分减100 { Dollars++; Cents-=100; } return temp; } void main( void) { Money m1(25,50),m2(105.7),m3(10.5,125); //m1=25元50分,m2=105元70分, //m3=10.5+125/100=11.75元 Money c,d; float e1,f1,e2,f2; m1.Show(); c= ++m1; //先加后用,即:先将m1加1,然后将m1赋给c (c=m1=25元51分) d= m1++; //先用后加,即:先将m1赋给d (d=m1=25元51分) // 然后将m1加1 (m1=25元52分) c.Show(); d.Show(); c=++m2; d=m2++; //c=m2=105元71分 //d=105元71分,m2=105元72分 c.Show(); d.Show(); e1=m2.GetAmount(f1); // m2=105元72分,f1=105,e1=72 e2=m3.GetAmount(f2); // m3=11元75分 ,f2=11, e2=75 cout< 程序执行后输出: 25元50分 25元51分 //e1+e2=72+75=147 第11章 友元与运算符重载 25元51分 105元71分 105元71分 116元147分 ·294· 说明: (1)Money为描述人民币的类,其数据成员Dollars、Cents分别代表元与分。 (2)在单参数的构造函数中,使用标准函数modff(n,&num)将实数n分为解为整数与小数两部分,返回小数值,整数值送到num所指单元中。最后将整数存入元Dollars中,小数部分乘100后存入分Cents中。 (3)前置“++”运算符重载函数中,先对人民币的分加1运算,分加1存在进位问题,当分加满100后,将分Cents减100(即分清零),再将元Dollars加1,最后通过return *this语句返回自加后的人民币币值。 (4)后置“++”运算符重载函数中,先将当前人民币币值赋给临时对象temp,然后对人民币的分加1运算,当分加满100后,将分Cents减100,再将元Dollars加1,最后通过return temp 返回自加前的人民币币值。 (5)主函数中 c= ++m1语句应解释为对前置重载函数的调用:c=m1.opreator(); d= m1++语句应解释为对后置重载函数的调用:d=m1.opreator(1); 【例11.10】定义描述三维空间点(x,y,z)的类,用友元函数实现“++”运算符的重载。 # include ThreeD( float a=0,float b=0,float c=0) { x=a;y=b;z=c;} ThreeD operator + (ThreeD & t) //二个点坐标相加的“+”运算符重载成员函数 { ThreeD temp; temp.x=x+t.x; temp.y=y+t.y; temp.z=z+t.z; return temp; } friend ThreeD & operator ++(ThreeD &); //坐标点前置“++”运算符重载友元函数 friend ThreeD operator ++(ThreeD &,int);//坐标点后置“++”运算符重载友元函数 ~ ThreeD() {} void Show() { cout<<\ }; ThreeD & operator ++ (ThreeD & t)