为啥我们在赋值运算符重载中使用引用返回而不是在加减运算中?
Posted
技术标签:
【中文标题】为啥我们在赋值运算符重载中使用引用返回而不是在加减运算中?【英文标题】:Why we use reference return in assignment operator overloading and not at plus-minus ops?为什么我们在赋值运算符重载中使用引用返回而不是在加减运算中? 【发布时间】:2014-02-24 11:02:54 【问题描述】:正如我在书籍和网络中所读到的,在 C++ 中,我们可以使用这些原型重载“加号”或“减号”运算符(作为 class Money
的成员函数):
const Money operator +(const Money& m2) const;
const Money operator -(const Money& m2) const;
对于赋值运算符:
const Money& operator =(const Money& m2);
为什么在赋值运算符重载中而不是在加号和减号运算符中使用对 Money 对象的引用作为返回值?
【问题讨论】:
如果您在+
或-
二进制操作中返回一个引用,它应该引用什么?返回引用是没有意义的。该操作必须创建一个新对象。
你不希望能够编码 a + b = c;
【参考方案1】:
从赋值返回引用允许链接:
a = b = c; // shorter than the equivalent "b = c; a = b;"
(如果运算符返回新值的副本,这也可以(在大多数情况下),但通常效率较低。)
我们不能从算术运算中返回引用,因为它们会产生一个新值。返回新值的唯一(明智的)方法是按值返回。
如您的示例那样,返回一个常量值会阻止移动语义,所以不要这样做。
【讨论】:
为什么?不,赋值链接与赋值运算符返回的内容有关。在任何版本中都可以使用赋值链接(如您的示例)。返回 const 引用将防止对 lhs 进行多次修改,如 '(a = b) = c',但这是另一回事。 换句话说,需要从赋值返回的非常量引用的情况相当深奥,通常属于“糟糕的编程实践”类别,因此人们甚至可能会看到一些明确推荐的来源 从赋值返回 const 引用。 @AndreyT:你说得对,我自己都搞糊涂了。 (当然,你必须返回一些东西以允许链接;但它可以是一个值或常量引用。)【参考方案2】:因为operator+
和operator-
不作用于this 对象,而是返回一个新对象,该对象是该对象与另一个对象的总和(或减法)。
operator=
是不同的,因为它实际上是分配一些东西给这个对象。
operator+=
和 operator-=
将作用于该对象,并且更接近于 operator=
。
【讨论】:
【参考方案3】:考虑一下您的要求。您可能希望表达式a + b
返回对a 或b 之一的引用,这将具有表达式的结果。因此,您可以将 a 或 b 中的一个修改为 a 和 b 的总和。因此,您可能希望将运算符 (+) 的语义重新定义为与运算符 (+=) 相同。就像@manuell 说的那样,您将因此允许(a + b) = c
。 += 和 -= 已经提供了您建议的语义。
【讨论】:
【参考方案4】:我认为如果你在重载的赋值运算符中按值返回就可以了,那是因为赋值运算符的关联性。考虑一下:
int a = b =c = 3 ;
这里的关联性如下: (a=(b=(c=3)))
但考虑iostream操作 cout
这里的关联性如下: (((cout
可以看到先打印x,所以如果在
还有一点,如果你按值返回,复制构造函数将被调用。 (这不是通过引用返回的情况)
【讨论】:
【参考方案5】:我猜下面显示的链接有更好的解释 return value of operator overloading in C++
【讨论】:
以上是关于为啥我们在赋值运算符重载中使用引用返回而不是在加减运算中?的主要内容,如果未能解决你的问题,请参考以下文章