this
是 C++
中的一个关键字,也是一个 const
指针,它指向当前对象地址(换句话说,其值为 &object
),通过它可以访问当前对象的所有成员。
我们知道类 class
是对象 object
的模板,所以在创建对象之前需要先定义类,类的定义包含属性(变量)和方法的定义。
类定义好后我们就可以通过类来创建多个实例对象,每个对象都有各自的实例属性(实例变量),但是非内联成员函数(non-inline member function)只会诞生一份函数实例(换句话说每个对象需要共用同一个方法来操作实例属性)。在有多个实例对象访问同一个函数时,函数如何知道该操作哪个对象的属性?此时就需要 this
指针。
编译器会隐式地传递 this
指针,this
指针如同一个句柄,此时方法将根据句柄来确定需要操作哪个对象的属性。调用静态方法时,则不会隐式地传递 this
指针,因为静态函数不与类实例对象相关联,即不属于某个对象拥有而由所有实例对象共享。
现在我们通过结合程序来说明并理解上一节所描述的原理,这里我们定义了类 Hello
,其中包含三个实例属性,以及一个使用属性的方法 setValue
,以 Hello
为模板创建了三个对象 object1, object2, object3
。
#include
using std::cout;
class Hello {
public:
int a;
int b;
int c;
Hello(int _a, int _b, int _c) {
a = _a;
b = _b;
c = _c;
}
void setValue(int _a, int _b, int _c) {
a = _a;
b = _b;
c = _c;
}
int getSum() {
return (a + b + c);
}
};
int main()
{
Hello object1(10, 20, 30);
Hello object2(20, 20, 10);
Hello object3(10, 10, 10);
cout << "Hello";
return 0;
}
将类 Hello
实例化时会根据类中定义的属性来创建每个对象各自的属性,确保各自数据完整性 object1::(a, b, c)
,object2::(a, b, c)
,object3::(a, b, c)
这一步就是将属性存放至每个对象各自的内存空间下。但是方法 setValue
则不会根据对象来创建多个,意味着 object1
,object2
,object3
需要共用同一个方法 setValue
来修改他们的实例属性。
为了保证方法 setValue
能够修改对象对应的属性,编译器隐式的向方法内传递 this
指针,this
指针指向的是当前对象的地址(注意 this
是指针类型,在 C/C++ 中要用 ->
运算符来访问成员)。
#include
using std::cout;
class Hello {
public:
int a;
int b;
int c;
Hello(int _a, int _b, int _c) {
this->a = _a;
this->b = _b;
this->c = _c;
}
void setValue(int _a, int _b, int _c) {
this->a = _a;
this->b = _b;
this->c = _c;
}
int getSum() {
return (this->a + this->b + this->c);
}
};
int main()
{
Hello object1(10, 20, 30);
Hello object2(20, 20, 10);
Hello object3(10, 10, 10);
cout << "Hello";
return 0;
}
当 object1
访问 setValue
时 this
表示 (Hello *)&object1
,当 object2
访问 setValue
时 this
表示 (Hello *)&object2
,当 object3
访问 setValue
时 this
表示 (Hello *)&object3
,如下程序所示(注意:下面程序不能运行,只是用于说明 this
指针的本质原理)。
#include
using std::cout;
class Hello {
public:
int a;
int b;
int c;
Hello(int _a, int _b, int _c) {
((Hello*)&object1)->a = _a;
((Hello*)&object1)->b = _b;
((Hello*)&object1)->c = _c;
}
void setValue(int _a, int _b, int _c) {
((Hello*)&object1)->a = _a;
((Hello*)&object1)->b = _b;
((Hello*)&object1)->c = _c;
}
int getSum() {
return (((Hello*)&object1)->a + ((Hello*)&object1)->b + ((Hello*)&object1)->c);
}
};
int main()
{
Hello object1(10, 20, 30);
Hello object2(20, 20, 10);
Hello object3(10, 10, 10);
cout << "Hello";
return 0;
}
在一个对象的某个成员函数中需要返回对象本身时可以 return *this;
来将对象返回。
class Hello {
public:
int a;
int b;
int c;
Hello & getObject() {
return *this;
}
};
当对象的实例属性与对象成员函数形参或局部变量相同时,如果需要访问或给对象的实例属性复制则需要使用 this
指针进行访问 this->a = a
,否则 a = a
访问的将是成员函数的形参或局部变量。
class Hello {
public:
int a;
int b;
int c;
Hello(int a, int b, int c) {
this->a = a;
this->b = b;
this->c = c;
}
};