使用 ostream 和链接的运算符重载.为什么要按引用返回? [英] operator overloading using ostream and chaining. Why return by reference?
问题描述
对此有很多问题和答案,但我真的找不到为什么我们需要通过引用返回.
There are many questions and answers for this, but I can't really find why we need to return by reference.
如果我们有(假设运算符已经为对象 MyObject 正确重载):
If we have (assume operator is already correctly overloaded for an object MyObject) :
MyObject obj1;
MyObject obj2;
cout << obj1 << obj2;
现在,会有像 ((cout << obj1) << obj2)); 这样的子表达式.问题是为什么不能按值返回?(好吧,让我们假设它允许返回 ostream 作为值)如果 cout <<
Now, there will be subexpressions like ((cout << obj1) << obj2)); The question is why can we not return by value ? (Ok, let's assume that it's allowed return ostream as value) If cout << obj1 return a stream object instead of a reference, what is the difference ? Why is chaining impossible then ? Just as with overloading of the '=' operator, we can't chain like A=B=C=D if we return by value. Why ?
感谢您的回答.我意识到我可以通过引用链接而不返回,但是当重载="时我的输出完全不同.如果我写:
Thank you for answers. I realize that I can chain without return by reference, but my output is quite different when overloading '='. If I write :
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){
Blah ret;
ret.x = rhs.x;
ret.y = rhs.y;
return ret;
}
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;
}
这个输出是:8,97,54,12,3
The output from this is : 8,9 7,5 4,1 2,3
但是如果我通过引用返回重载并将参数设置为引用,并在重载时修改并返回*this,我得到:2,32,32,32,3
But if I overload with return by reference and set the parameter as reference, and modify and return *this when overloading instead, I get : 2,3 2,3 2,3 2,3
在第一个示例中没有更改对象的原因是什么?是因为左值还是右值?相比之下,速记运算符怎么样?
What is the reason no objects are altered in the first example ? Is it because of lvalues vs rvalues ? How about shorthand operators in comparison?
好的,另一个更新.如前所述,正确的结果应该是 2,3.但是,如果我将重载运算符写为:
Ok, another update. As mentioned, the correct result should be 2,3 for all. However, if I write the overloaded operator as :
Blah Blah::operator =(Blah rhs){
x = rhs.x;
y = rhs.y;
return *this;
}
然后,我会得到正确的结果.(2,3 2,3 2,3 2,3).*this 会发生什么?重载运算符在重载函数中用 rhs 更新 lhs,但返回 *this 似乎毫无意义.*this 在哪里结束: b3 = b4 = b2 = b1 ?它是否会尝试向左返回,以便在链到达 b3 时实际上什么都不返回(即会尝试向左返回)?
Then, I will get correct results. (2,3 2,3 2,3 2,3). What happens to *this ? The overloaded operator update the lhs with rhs in the overload function, but returning *this seem to be pointless. Where does *this end up in : b3 = b4 = b2 = b1 ? Will it try to return to the left, so that it actually returns nothing when the chain reaches b3 (That will try to return to the left)?
推荐答案
主要是因为按值返回做了一个副本,而iostream 对象不可复制.他们有状态和身份,并且不清楚复制它们意味着什么:对象包含(至少在逻辑上)它在流,所以如果我创建一个副本,我有两个对象在流中的相同位置写入.
The main reason is because returning by value makes a copy, and iostream objects are not copyable. They have state and identity, and it's not clear what copying them should mean: the object contains (logically, at least) its position in the stream, so if I create a copy, I have two objects which will write at the same position in the stream.
这篇关于使用 ostream 和链接的运算符重载.为什么要按引用返回?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!