'this' C++ 中的指针行为

'this' pointer behaviour in c++

本文关键字:指针 C++ this      更新时间:2023-10-16

我对C++中的这个指针有基本的理解

#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;
}

我的问题是,当我在SetX和SetY函数中返回this指针,但没有将返回类型声明为指针时,编译器为什么不报告错误?

这是因为您返回的是*this而不是this

this是指向类型为Test的对象的指针。这意味着this-变量基本上保存了存储对象的地址。要访问this指向的对象,请使用*

因此,您正在返回this指针指向的实际对象。


编辑

代码不能按您希望的方式工作的问题是由您正在处理堆栈这一事实引起的。

让我们看看地址:

#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;
cout << this << endl; // >> 0x29ff18
return *this;
}
void print() { cout << "x = " << x << " y = " << y << endl; }
};
int main()
{
Test obj1;
cout << &obj1 << endl; // >> 0x29ff10
obj1 = obj1.setX(10).setY(20);
cout << &obj1 << endl; // >> 0x29ff10
//obj1.setY(20);
obj1.print();
return 0;
}

如您所见,与main相比,this指向的对象在setY方法中的地址不同。这是因为对象被复制到setY方法的堆栈帧中,所以在setXsetY中,您使用的是obj1副本

如果您正在执行obj1.setX(10).setY(20);,则基本上复制对象obj1并在setX中使用它,然后在setY中使用setX的返回对象。如果要保存最后一个副本,则必须将其重新分配给obj1

您的问题解决方案有效,但效率极低。描述正在发生的事情的最后一段是不正确的。setx是用obj1调用的,并使用obj1。sety使用obj1的副本进行调用。然后分配obj1由sety返回的obj1副本的副本。地址不会更改,因为obj1的存储正在被覆盖,而不是被替换。添加一个复制构造函数和一个赋值运算符,您就可以观察实际发生的事情。建议的解决方案是在整个过程中使用对同一对象的引用,并根据@πάγτα进行链接ῥεῖ 's的答案如下user4581301

我的问题是,当我在SetX和SetY函数中返回this指针,但没有将返回类型声明为指针时,编译器为什么不报告错误?

这是完全有效的语法,因此编译器不应该返回错误消息。问题是您使用的是返回类型为this*的副本。


要正确连锁操作以在原始实例上操作,请返回对this:的引用

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

否则,您将返回一个不相关的类副本。