我们在前面学习了重载运算符,赋予C++运算符多种含义。
但是我们还没有更深入的理解重载运算符和友元函数之间的爱恨情仇
我们先看作为类成员的重载运算符的例子
#include<iostream>
using namespace std;
class AA
{
private:
int a_;
public:
AA(int a)
{
a_ = a;
}
int operator+(int x)
{
return a_ + x;
}
};
int main()
{
AA a = { 2 };
int b = 8;
cout << a + b << endl;//结果是10
cout << b + a << endl;//这是不行的
}
我们发现把左操作数和右操作数换个位置就发现不行了
这是为什么呢?
因为调用重载运算符的规则是左操作数是调用对象
也就是说上面这个例子里,a+b会被展开为a.operator+(b);
而b+a无法被展开
那我们怎么做呢?
有人说,我们再像下面再定义一个的不就好了吗
class AA
{
private:
int a_;
public:
AA(int a)
{
a_ = a;
}
int operator+(int x)
{
return a_ + x;
}
int operator+(int x, AA t)//编译器不允许的
{
return x+t.a_
}
};
但是问题来了,这是编译器不允许的
那我们到底怎么解决这个问题呢?答案是用友元函数
要为类重载运算符,并将非类的项作为其第一个操作数,则可以用友元函数来反转操作数的顺序
#include<iostream>
using namespace std;
class AA
{
private:
int a_;
public:
AA(int a)
{
a_ = a;
}
int operator+(int x)
{
return a_ + x;
}
friend int operator+(int x, AA t);//告诉编译器,这个函数是AA类的朋友,可以访问AA类的私有数据
};
int operator+(int x, AA t)
{
return x + t.a_;
}
int main()
{
AA a = { 2 };
int b = 8;
AA c = { 10 };
cout << a + b << endl;
cout << b + a << endl;
cout << b + a + c << endl;
cout << a + b + c<< endl;
}
这下子我们就解决这个问题啦,我们甚至发现居然可以连加
这是因为C++从左至右读取语句
a+b+c被展开为a.operator+(b+c)
再被展开为a.operator+(operator+(b,c));