提问人:Ajay kumar soni 提问时间:8/6/2021 最后编辑:einpoklumAjay kumar soni 更新时间:8/6/2021 访问量:105
从 setter 方法返回 *this 时,对象变得不可变
Object becomes immutable when returning *this from a setter method
问:
我正在了解这个指针,它包含调用该函数的当前对象的地址。但是当我从成员函数返回当前对象时,我对这个指针有疑问。
#include<bits/stdc++.h>
using namespace std;
class Point
{
private:
int x,y;
public:
Point(int x,int y)
{
this->x = x;
this->y = y;
//cout<<this<<endl;
}
Point setX(int x)
{
this->x = x;
//cout<<this<<endl;
return *this;
}
Point setY(int y)
{
this->y = y;
//cout<<this<<endl;
return *this;
}
int getX()
{
return x;
}
int getY()
{
return y;
}
};
int main()
{
Point p(10,20);
cout<<p.getX()<<" "<<p.getY()<<endl;
p.setX(1000).setY(2000);
cout<<p.getX()<<" "<<p.getY();
return 0;
}
为什么 p.setX(1000).setY(2000) 只修改 x 的值,而不是 y? 为什么在第二个 cout 语句答案是 1000 20,但它应该是 1000 2000?
答:
1赞
songyuanyao
8/6/2021
#1
因为 (and ) 返回 by-value。在 中,返回一个临时的(复制自 ),在其上调用,任何修改都与 无关。setX
setY
p.setX(1000).setY(2000);
p.setX(1000)
Point
*this
setY
setY
p
将它们更改为按引用传递。
Point& setX(int x)
// ^
{
this->x = x;
//cout<<this<<endl;
return *this;
}
Point& setY(int y)
// ^
{
this->y = y;
//cout<<this<<endl;
return *this;
}
评论
0赞
Ajay kumar soni
8/6/2021
所以你是说 p.setX(1000) 正在对其从 *this 复制的对象进行更改。既然它正在更改其本地对象副本中的值,那么为什么更改会反映回 p.x 值中。
0赞
songyuanyao
8/6/2021
@Ajaykumarsoni 不,我是说. changed ,则返回一个副本,然后对 copy 进行调用,对 copy 进行更改。副本将立即销毁,仅保留更改。setY
p.setX(1000)
p.x
setY(2000)
y
p.x
0赞
Ajay kumar soni
8/6/2021
好的,现在我明白了。由于我返回的是 Point 类型,因此 (*this) 将创建一个本地 Point 对象并返回它,然后在此本地对象上调用 setY(2000)。在这个本地返回的对象上,y 值将被更改。最初,我以为既然我从 setX 返回 (*this),那么 setX 将从中返回当前调用对象 (p)。然后它将在同一个对象上调用 setY。但相反,setX 将创建一个本地对象,然后它将返回。如果我在某个地方错了,请纠正我?
0赞
songyuanyao
8/6/2021
@Ajaykumarsoni 你是对的。这就是为什么更改为按引用返回可以解决此问题的原因;它使返回当前对象而不是副本。setX
3赞
einpoklum
8/6/2021
#2
原因是 your 和 methods 返回一个 - 它们返回对象的副本。因此,您设置的是点的临时副本的成员,而不是原始点的成员。setX()
setY()
Point
setY()
y
您可以通过将签名从以下位置更改为以下位置来纠正此问题:
Point setX(int x)
自:
Point& setX(int x)
同样,对于 .您会注意到返回类型现在是 - 对对象的引用。setY()
Point&
Point
但是请注意,类的 getter 和 setter 方法有效地允许处理和喜欢公共对象。因此,除非你打算用坐标的一些隐式表示来替换它们(例如,有角度+与原点的距离),在这种情况下,setter和getter变得有趣 - 你也可以考虑将你的类简化为:x
y
struct Point { int x, y; }
简单的设计通常是合适的。
最后,与您的特定问题无关,您的代码以几行不合时宜的行开头......
评论
0赞
Ajay kumar soni
8/6/2021
但我还有其他疑问。由于这是一个指针,因此即使它返回当前调用对象的副本,它也应该更改 y 的值。
0赞
einpoklum
8/6/2021
@Ajaykumarsoni:但是你不回来了。返回 ,取消引用 。现在,类型是 ;但是返回类型是 ,因此会创建并返回副本。this
*this
this
*this
Point&
Point
0赞
Ajay kumar soni
8/6/2021
好的,现在我明白了。由于我返回的是 Point 类型,因此 (*this) 将创建一个本地 Point 对象并返回它,然后在此本地对象上调用 setY(2000)。在这个本地返回的对象上,y 值将被更改。最初,我以为既然我从 setX 返回 (*this),那么 setX 将从中返回当前调用对象 (p)。然后它将在同一个对象上调用 setY。但相反,setX 将创建一个本地对象,然后它将返回。如果我在某个地方错了,请纠正我?
评论
setX
并按值返回其点,而不是按引用返回。这意味着,当您 时,您将返回要调用该方法的对象的副本。setY
return *this
Point
*this
Point&
setX(int)
setY(int)
void
Point