函数应该返回引用还是对象?

4
让我们讨论这两个函数:
  1. complex& operator+=(const T& val);
  2. complex operator+(const T& val);
其中,“complex”是实现复数变量的类名。
第一个函数返回引用,以便可以写a+=b+=c(相当于b=b+c; a=a+b;)。
第二个函数返回对象(不是引用),但我们仍然可以写a=b+c+d。
谁能解释一下这个细微差别?返回引用或对象有什么区别?
5个回答

4

赋值运算符支持对同一对象进行多次应用:

(a += b) += c;

这将同时向a中添加b和c。为了使其正常工作,a += b必须返回对a的引用。然而,加法运算符不需要这样做,因为表达式b + c + d没有副作用。只有对a的最终赋值才具有副作用。

2
在1中,a+=b操作符会修改a的值。因此它可以返回对自身的引用,因为a本身是该操作的正确结果。
然而,在2中需要一个新对象,因为a+b返回的不是a,所以返回对a的引用是不正确的。

1

细微之处在于你所给出的例子。

从 + 运算符中,你期望得到与开始时不同的两个值:b+c 既不是 b 也不是 c,它是其他东西。因此,我们不能返回对 b 或 c 的引用……除非在堆栈上分配一个新对象,否则这将是我们唯一可以使用的两个对象。因此,我们必须返回一个值。

而且,你已经解释了为什么 += 运算符返回它所返回的内容。


1

因为complex& operator+=(const T& val);操作的是this,而complex operator+(const T& val);必须为和创建一个新的临时对象。

如果你从+=返回一个对象,它可能会做你期望的事情,但其中可能会有一些额外的副本。正如你所提到的,如果你想要链接调用,你会希望这种行为。如果你返回一个临时对象并写(a += b) += c,当它在临时对象中被销毁时,你添加的c将会丢失。

如果你从+返回一个引用,你将得到一个指向临时对象的引用,你的程序将具有未定义的行为。你可以写a=b+c+d,因为b+c创建了一个临时变量b1b1 + d创建了一个临时变量b2,然后将其分配给a


0
在第一种情况下,您正在将某些内容添加到左侧的对象中,但表达式的值是左侧的对象。因此,您正在通过引用返回某些内容(通常是左侧)。例如:
cout << (a+=b)

在第二种情况下,您正在添加两个对象并获得第三个对象,您可以在堆栈上执行此计算,因此您通过值而不是引用返回实际对象。 例如:
if(...)
{
    T a = b + c;
    cout << a;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接