运算符重载(混淆为什么要调用此运算符)C ++

时间:2018-01-31 10:11:37

标签: c++

以下是代码:

#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;?一般来说,你可以解释这些重载运算符之间的差异吗?

4 个答案:

答案 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+xx+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;