以下是代码:
#include <iostream>
using namespace std;
class X {
public:
int x;
X(int x=6) : x{x} {}
void print() {cout << x;}
X operator+(int rop) const {
return rop + x;
}
int operator+(const X& rop)const {
return x+rop.x;
}
};
X operator+(int lop, const X& x) {
return 2*lop + x.x;
}
int main()
{
X x;
cout << (5+x) + (x+2);
x.print();
return 0;
}
这里我们看到了不同的重载运算符,它们会超载。
我的( 5+x)
示例名为2*lop + x.x;
,而(x + 2)rop + x;
(我猜){/ p>
但我真的不明白为什么(特别是在第一种情况下)调用了(5 + x)2*lop + x.x;
?一般来说,你可以解释这些重载运算符之间的差异吗?
答案 0 :(得分:3)
您的运营商各不相同:
一个适用于X + int
/ X.operator+(int)
:
X operator+(int rop) const {
return rop + x;
}
X + X
/ X.operator+(X)
的下一个:
int operator+(const X& rop)const {
return x+rop.x;
}
和int + X
的最后一个(必须是自由函数,因为无法重载int.operator+
):
X operator+(int lop, const X& x) {
return 2*lop + x.x;
}
答案 1 :(得分:2)
如果将运算符定义为类成员,则左操作数是类,右操作符是参数列表中的操作符。像:
X operator+(int rop) const;
在您调用它时,int
应该是右操作数。
如果在外面定义,那么它只是正常顺序,左边第一个,右边第二个。
因此,对于(5 + x)
,类X
中定义的运算符无法匹配,并且外部定义的运算符匹配。
答案 2 :(得分:2)
如果a + b
是具有重载a.operator+(b)
成员函数的对象,则a
通常等于operator+
。否则编译器会尝试调用operator+(a, b)
。
对于x + 2
,真正被称为x.operator+(2)
。
无法使用5 + x
,因为不可能5.operator+(x)
。相反,必须使用全局函数。
答案 3 :(得分:0)
目前您的加法表达
(5+x) + (x+2)
没有优化编译
x.X::operator+(2).X::operator+(operator+(5, x))
(至少在GCC 7.3中,我认为5+x
和x+2
的评估顺序可以根据编译器进行反转)
operator+(int rop)
并非绝对必要。它被用于第一次添加(int 2),因为它比通过构造函数的隐式转换将int
转换为X更好。如果省略
operator+(int rop)
然后你会得到
X::X(x.X::operator+(X::X(2))).X::operator+(operator+(5, x))
在两种优化的情况下,这都简化为
std::cout << 24;
std::cout << 6;