下面给出的程序打印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 任何人都可以解释为什么会这样吗?
答案 0 :(得分:2)
当您返回普通对象而不是引用时,您将返回调用该方法的对象的副本。 <{1}}作用于该副本(这是一个临时副本),然后该副本被破坏。
当您返回引用时,所有调用都对同一个对象进行操作,因此您可以获得所需的行为。
答案 1 :(得分:2)
第一次调用setX()
会返回 obj1
的临时副本,并且对setY()
的调用会修改该临时副本。对print()
的后续调用会显示obj1
的状态,因为在obj1
中y
成员变量从未被修改过,所以它保持为零。
当您使用引用替换返回类型时,不会对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本身起作用。因此输出。