函数应该返回引用还是对象?
我们来讨论一下这两个函数:
- complex&operator+=(const T& val);
- 复杂运算符+(const T& val);
其中“complex”是实现例如复杂变量的类的名称。
因此,第一个运算符返回引用,以便可以编写 a+=b+=c (相当于 b=b+c; a=a+b;)。
第二个运算符返回 objec(不是引用),我们仍然可以写 a=b+c+d。
谁能给我解释一下这个细微差别?返回引用或对象有什么区别?
Let's discuss these two functions:
- complex& operator+=(const T& val);
- complex operator+(const T& val);
Where "complex" is a name of a class that implements for example complex variable.
So first operator returnes reference in order to be possible to write a+=b+=c ( which is equivalent to b=b+c; a=a+b;).
Second operator returnes and objec(NOT A REFERENCE), be we still able to write a=b+c+d.
Who could explain me this nuance? What is the difference between returning reference or object?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
赋值运算符支持对同一对象进行多次应用:
这会将
b
和c
添加到a
中。为此,a += b
必须返回对a
的引用。然而,加法运算符不需要这样做,因为表达式b + c + d
没有副作用。只有对a
的最终赋值才会产生副作用。The assignment operators support multiple application to the same object:
Which will add both
b
andc
toa
. For this to work,a += b
must return a reference toa
. The addition operator, however, doesn't require this, since the expressionb + c + d
has no side-effect. Only the final assignment toa
has a side-effect.在 1 中,a+=b,+= 运算符修改 a。因此它可以返回对自身的引用,因为a本身就是操作的正确结果。
然而,在 2. 中,需要一个新对象,因为 a+b 返回的不是 a,因此返回对 a 的引用是不正确的。
In 1, a+=b, the += operator modifies a. Therefore it can return a reference to itself, because a itself is the correct result of the operation.
However, in 2. a new object is required because a+b returns something that is not a, so returning a reference to a wouldn't be correct.
在某种程度上,细微差别在于你给出的例子。
从 + 运算符中,您期望返回与开始时的两个值不同的值:b+c 既不是 b 也不是 c,它是别的东西。因此,我们无法返回对 b 或 c 的引用......并且无法在堆栈上分配新对象,这将是我们必须使用的唯一两个对象。因此我们必须返回一个值。
您已经解释了为什么 += 运算符会返回它的作用。
The nuance is in the examples you give, in a way.
From the + operator you expect to get back a different value from the two you started with: b+c is neither b nor c, it's something else. Thus we can't return references to either b or c ... and short of allocating a new object on the stack those will be the only two we have to work with. Thus we have to return a value.
And you've already explained yourself why the += operator returns what it does.
因为
复杂& operator+=(const T& val);
对this
进行操作,因为复杂的operator+(const T& val);
必须为 sum 创建一个新的临时对象。如果您要从
+=
返回一个对象,它可能会执行您期望的操作,但其中可能会有一些额外的副本。正如您所提到的,如果您想链接调用,您将想要这种行为。如果您返回一个临时对象并写入(a += b) += c
,那么您添加的c
在临时对象中被销毁时将会丢失。如果您要从
+
返回引用,则您将获得一个临时引用,并且您的程序将具有未定义的行为。您可以编写a=b+c+d
因为b+c
创建临时b1
和b1 + d
创建一个临时b2
,然后将其分配给a
。Because
complex& operator+=(const T& val);
operates onthis
and becausecomplex operator+(const T& val);
must create a new temporary object for the sum.If you were to return an object from
+=
, it would probably do what you expect, but there might be some extra copies in there. As you mentioned, you would want this behavior if you want to chain calls. If you returned a temporary and wrote(a += b) += c
, your addition ofc
would be lost when it's destroyed in the temporary.If you were to return a reference from
+
, you'd have a reference to a temporary and your program would have undefined behavior. You can writea=b+c+d
becauseb+c
creates a temporaryb1
andb1 + d
creates a temporaryb2
, which is then assigned toa
.在第一种情况下,您向左侧的对象添加一些内容,但表达式的值是左侧的对象。所以你通过引用返回一些东西(通常是左边)。例如:
在第二种情况下,您添加两个对象并获取第三个对象,并且您可以在堆栈上执行此计算,因此您将按值而不是按引用返回实际对象。
例如:
In the first case, you are adding something to the object on the left, but the value of the expression is the object on the left. So you are returning something (usually the left) by reference. For example:
In the second case, you are adding two objects and getting a third object, and you can do this calculation on the stack, so you are returning an actual object by value rather than by reference.
For example: