简体   繁体   English

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

[英]Why return by reference while overloading = operator?

I know there's plenty of questions on this already, so please bear with me on this one.我知道这方面已经有很多问题了,所以请多多包涵。

So I found this question, and I had a doubt about a modification of 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;
}

So I haven't used return by reference here, while overloading the = operator, and I still get the expected output.所以我在这里没有使用return by reference,同时重载=运算符,我仍然得到预期的output。

Why should I return by reference?为什么要通过引用返回? The only difference I see is that copy constructor is called while returning by value but no copy constructor is called while returning by reference.我看到的唯一区别是在按值返回时调用了复制构造函数,但在按引用返回时没有调用复制构造函数。

Could someone please dumb things down for me and explain the concept/idea behind returning by reference?有人可以帮我把事情搞砸并解释通过引用返回背后的概念/想法吗? It was taught in my class around almost a year ago, and I still don't understand it.大约一年前在我的 class 中教过它,但我仍然不明白。

There is no strict right and wrong here.这里没有严格的对与错。 You can do weird things with operator overloads and sometimes it is appropriate.你可以用运算符重载做一些奇怪的事情,有时它是合适的。 However, there is rarely a good reason to return a new instance from operator= .但是,很少有充分的理由从operator=返回一个新实例。

The return value is to enable chaining.返回值是启用链接。 Your test for chaining is incomplete.您的链接测试不完整。 Your line:您的线路:

b3 = b4 = b2 = b1;

is the same as是相同的

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

And you see expected output for this case.对于这种情况,您会看到预期的 output。 However, chaining like this但是,像这样链接

(b3 = b4) = b1;

is expected to first assign b4 to b3 then assign b1 to b3 .预计首先将b4分配给b3 ,然后将b1分配给b3 Or you might want to call a method on the returned reference:或者您可能想在返回的引用上调用一个方法:

(b3 = b4).foo();

As you return a copy, the second assignment will be to a temporary and the member function foo will be called on a temporary, not on b3 as expected.当您返回副本时,第二个分配将是临时的,成员 function foo将在临时调用,而不是像预期的那样在b3上调用。 To see this in action consider the output of this要看到这一点,请考虑这个的 output

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;
}

when returning a copy:返回副本时:

7, 5
2, 3

and when returning a reference:并在返回参考时:

2, 3
2, 3

The much simpler reason is that you do not want to return a copy when there is no need to make a copy.更简单的原因是您不想在不需要制作副本时退回副本。

Why return by reference while overloading = operator?为什么在重载 = 运算符时按引用返回?

Because:因为:

  • Copying is sometimes expensive, in which case it is good to avoid.复制有时很昂贵,在这种情况下最好避免。
  • It is conventional.这是常规的。 That is also how the built in assignment operators of fundamental types, compiler generated assignment operators of classes, and all the assignment operators of standard types (as far as I know) work.这也是基本类型的内置赋值运算符、编译器生成的类的赋值运算符以及所有标准类型的赋值运算符(据我所知)的工作方式。

Given that the special member functions that you've defined don't do anything special, I recommend following class definition instead:鉴于您定义的特殊成员函数没有做任何特殊的事情,我建议改为遵循 class 定义:

struct Blah {
    int x;
    int y;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM