为什么在重载=运算符时按引用返回?

时间:2020-07-22 18:57:21

标签: c++ constructor operator-overloading

我知道对此已经有很多问题,所以请允许我接受这一问题。

因此,我发现了this个问题,对此有所疑问。

class Blah {
public:
    Blah();
    Blah(int x, int y);
    int x;
    int y;
    Blah operator =(Blah rhs);
};
Blah::Blah() {}
Blah::Blah(int xp, int yp) {
    x = xp;
    y = yp;
}
Blah Blah::operator =(Blah rhs) {
    x = rhs.x;
    y = rhs.y;
    return *this;
}
int main() {

    Blah b1(2, 3);
    Blah b2(4, 1);
    Blah b3(8, 9);
    Blah b4(7, 5);
    b3 = b4 = b2 = b1;
    cout << b3.x << ", " << b3.y << endl;
    cout << b4.x << ", " << b4.y << endl;
    cout << b2.x << ", " << b2.y << endl;
    cout << b1.x << ", " << b1.y << endl;
    return 0;
}

因此,在重载=运算符时,我没有在这里使用按引用返回,而且仍然可以获得预期的输出。

我为什么要通过参考归还?我看到的唯一区别是,按值返回时将调用复制构造函数,而按引用返回时将不调用复制构造函数。

有人可以帮我愚弄一下东西,并解释一下通过参考归还的概念/想法吗?大约一年前,它在我的课堂上教过,但我仍然听不懂。

2 个答案:

答案 0 :(得分:3)

这里没有严格的对与错。您可以使用运算符重载来做奇怪的事情,有时这是适当的。但是,很少有充分的理由从operator=返回新实例。

返回值是启用链接。您的链接测试不完整。您的行:

b3 = b4 = b2 = b1;

相同
b3 = (b4 = (b2 = b1));

您会看到这种情况的预期输出。但是,像这样

(b3 = b4) = b1;
预计

首先将b4分配给b3,然后将b1分配给b3。或者您可能想在返回的引用上调用方法:

(b3 = b4).foo();

当您返回副本时,第二个分配将是临时的,成员函数foo将在临时上而不是在b3上被调用。要查看实际效果,请考虑此输出

int main() {

    Blah b1(2, 3);
    Blah b2(4, 1);
    Blah b3(8, 9);
    Blah b4(7, 5);        
    (b3 = b4) = b1;
    cout << b3.x << ", " << b3.y << endl;
    cout << b1.x << ", " << b1.y << endl;
    return 0;
}

返回副本时:

7, 5
2, 3

以及返回引用时:

2, 3
2, 3

更简单的原因是,您不需要复制时就不想返回副本。

答案 1 :(得分:2)

为什么在重载=运算符时按引用返回?

因为:

  • 有时复制很昂贵,在这种情况下最好避免复制。
  • 这是常规的。这也是基本类型的内置赋值运算符,编译器生成的类的赋值运算符以及所有标准类型的赋值运算符(据我所知)的工作方式。

鉴于您定义的特殊成员函数没有做任何特殊的事情,我建议改用以下类定义:

struct Blah {
    int x;
    int y;
};