令人困惑的输出

时间:2012-09-15 13:32:22

标签: c++ return

下面给出的程序打印x = 10 y = 0

#include<iostream>
using namespace std;

class Test
{
private:
  int x;
  int y;
public:
  Test (int x = 0, int y = 0) { this->x = x; this->y = y; }
  Test setX(int a) { x = a; return *this; }
  Test setY(int b) { y = b; return *this; }
  void print() { cout << "x = " << x << " y = " << y << endl; }
};

int main()
{
  Test obj1;
  obj1.setX(10).setY(20);
  obj1.print();
  return 0;
}

但如果我们更换

Test setX(int a) { x = a; return *this; }
Test setY(int b) { y = b; return *this; }

Test &setX(int a) { x = a; return *this; }
Test &setY(int b) { y = b; return *this; }

输出为x = 10 y = 20 任何人都可以解释为什么会这样吗?

4 个答案:

答案 0 :(得分:2)

当您返回普通对象而不是引用时,您将返回调用该方法的对象的副本。 <{1}}作用于该副本(这是一个临时副本),然后该副本被破坏。

当您返回引用时,所有调用都对同一个对象进行操作,因此您可以获得所需的行为。

答案 1 :(得分:2)

第一次调用setX()会返回 obj1的临时副本,并且对setY()的调用会修改该临时副本。对print()的后续调用会显示obj1的状态,因为在obj1y成员变量从未被修改过,所以它保持为零。

当您使用引用替换返回类型时,不会对setX()setY()的{​​{1}}和obj进行临时复制。

答案 2 :(得分:1)

让我们回到基于面向对象编程的基础。

让我们用一个比喻 - 说一辆公共汽车。

总线具有某些可以更改的属性 - 例如燃料

因此,如果你有一个功能(补充燃料),你不需要一个与最后一个油位完全相同的新总线。

回到最初的问题。

Test setX(int a) { x = a; return *this; }

应该阅读

void setX(int a) { x = a; }

你有相同的物体,但燃料可能加满(或在这种情况下为x)

答案 3 :(得分:0)

在第一种情况下,您将按值返回对象,因此将创建并返回对象的副本。 所以
obj1.setX(10)将返回test的副本,而.setY(20)将对该副本起作用,这就是为什么它的效果不在obj1上。
在第二种情况下,返回对象的引用,因此.setY(20)将对obj1本身起作用。因此输出。