在上一篇文章中,我们介绍了operator函数的功能,可以实现:
c=a.operator+(b);//即c=a+b;
但是如果我们想实现:
c=a+100;
就会出错,因为我们定义的是两个对象相应的数据相加,而100是一个常量,这时该如何解决这个问题呢?
【EG】编写一个用于进行分数加法计算的类
#include<iostream>
using namespace std;
class fenshu
{
private:
long fenzi;
long fenmu;
long gys(long a,long b);//求最大公约数
public:
fenshu()
{
fenzi=0;fenmu=1;
}
fenshu(long a,long b);
void disp();
fenshu operator+(fenshu &dt);
fenshu operator+(long dt);
};
void fenshu::disp()
{
cout<<fenzi<<"/"<<fenmu<<endl;
}
fenshu::fenshu(long a,long b)
{
long x;
x=gys(a,b);
fenzi=a/x;
fenmu=b/x;
}
fenshu fenshu::operator+(fenshu &dt)
{
long xinfenzi,xinfenmu;
xinfenmu=fenmu*dt.fenmu;
xinfenzi=fenzi*dt.fenmu+dt.fenzi*fenmu;
return fenshu(xinfenzi,xinfenmu);
}
fenshu fenshu::operator+(long dt)
{
return fenshu(dt*fenmu+fenzi,fenmu);
}
long fenshu::gys(long a,long b)
{
long x;
while(b!=0)
{
a=a%b;
x=a;a=b;b=x;
}
return a;
}
int main()
{
fenshu a(2,16),b(1,6),c(5,1),d;
cout<<"初始值:"<<endl;
a.disp();
b.disp();
c.disp();
d.disp();
cout<<"a+b的结果:"<<endl;
c=a+b;
c.disp();
cout<<"a+2的结果:"<<endl;
c=a+2;
c.disp();
}
在上面的程序中,求最大公约数的函数只在类的成员函数中使用,因此,把它的访问权限设置成private。
上述例子中尽管实现了运算符的重载,但是要实现下面语句的话,还是会出错:
c=2+a;
c=2.operator+(a);
因为常量2不是fenshu类的对象,所以该语句不能运行。
那么想要解决这个问题,又该怎么操作呢?
需要将operator+()函数说明为fenshu类的友元。
利用operator函数进行运算时,第一个参数必须是对象,不能是常量。
但是对于友元函数来讲,由于运算所需要的所有参数都必须作为函数的参数来进行处理,因此,即使运算所需的第一个参数是数值,也可以正确的运算。
#include<iostream>
using namespace std;
class fenshu
{
private:
long fenzi;
long fenmu;
long gys(long a,long b);
public:
fenshu()
{
fenzi=0;fenmu=1;
}
fenshu(long a,long b);
void disp();
fenshu operator+(fenshu &dt);
fenshu operator+(long dt);
friend fenshu operator+(long dt1,fenshu &dt2);
};
void fenshu::disp()
{
cout<<fenzi<<"/"<<fenmu<<endl;
}
fenshu::fenshu(long a,long b)
{
long x;
x=gys(a,b);
fenzi=a/x;
fenmu=b/x;
}
fenshu fenshu::operator+(fenshu &dt)
{
int xinfenzi,xinfenmu;
xinfenzi=dt.fenzi*fenmu+fenzi*dt.fenmu;
xinfenmu=dt.fenmu*fenmu;
return fenshu(xinfenzi,xinfenmu);
}
fenshu fenshu::operator+(long dt)
{
return fenshu(dt*fenmu+fenzi,fenmu);
}
long fenshu::gys(long a,long b)
{
long x;
while(b!=0)
{
a=a%b;
x=a;a=b;b=x;
}
return a;
}
fenshu operator+(long dt1,fenshu &dt2)
{
return fenshu(dt1*dt2.fenmu+dt2.fenzi,dt2.fenmu);
}
int main()
{
fenshu x(1,4),y;
y=x+2;
y.disp();
y=2+x;
y.disp();
}
现在的程序就是即可实现y=2+x,也可以实现y=x+2。
程序中有一句话
fenshu operator+(long dt1,fenshu &dt2)
问这两个参数可以调换吗?答案是不可以的,必须跟类中定义友元函数保持一致,否则会出错。
当将operator+()函数作为类的友元来定义时,应保证至少有一个参数是类的对象,否则,若两个参数都是数值,如进行2+3这样的运算时,系统将出现编译错误。
fenshu fenshu::operator+(long dt)
{
return fenshu(dt*fenmu+fenzi,fenmu);
}
不可以改写成
fenshu& fenshu::operator+(long dt)
{
return fenshu(dt*fenmu+fenzi,fenmu);
}
因为该函数的返回值是利用构造函数创建的临时局部对象,函数调用结束时参数的存储空间被释放掉了,所以局部对象是不能返回其引用或者指针的。
用老师的话说:你连房子都没有,要门牌号有啥用啊???