2

下面给出的程序打印 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

5 回答 5

4

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

当你返回一个引用时,所有的调用都在同一个对象上操作,所以你得到了你正在寻找的行为。

于 2012-09-15T13:34:56.493 回答
2

第一次调用setX()返回临时副本obj1调用setY()修改临时副本。随后的调用print()显示状态,obj1并且由于在obj1成员y变量中从未被修改过,它保持为零。

当您用引用替换返回类型时,不会对调用setX()setY()操作进行临时复制obj

于 2012-09-15T13:35:04.077 回答
1

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

让我们用一个比喻——比如一辆公共汽车。

公共汽车具有某些可以更改的属性 - 例如燃料。

因此,如果您有一个功能(加满燃料),您不需要一辆与最后一辆完全相同且油箱已满的新巴士。

所以回到最初的问题。

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

应该读

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

等等

您有相同的对象,但燃料可能已加满(或在这种情况下为 x)

于 2012-09-15T13:54:41.470 回答
0

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

于 2015-07-17T06:42:18.863 回答
-1

这个 pinter 包含一个对象的地址 在 setx fun 的第一种情况下,这个指针返回 x 并且不能同时返回 y 值,然后他发送 y 的副本而不是 y 的地址。在第二种情况下,这两个函数都不同,都有自己的 this 指针,所以它们发送 x 和 y 的地址

于 2022-01-13T10:04:57.533 回答