this
是一个指向当前对象的指针,它可以在类的成员函数中使用。它是每个类的非静态成员函数的隐含参数;当你在类的成员函数中使用 this
时,它指向调用该函数的对象。主要作用是让类的成员函数能够访问对象的成员变量和其他成员函数。因为每个对象都有自己的成员变量,所以需要一种方法来确定成员函数是在哪个对象上调用的,这就是 this
指针的作用。
需要this指针的原因是因为类的成员变量和成员方法在内存中存储的方法不同:
成员变量:
成员变量存储在对象的内存空间中。每个类的对象都会在内存中分配一块区域来存储其成员变量的值。当创建类的对象时,编译器会根据类的定义确定每个成员变量的大小,并将它们分配在对象的内存中。对象的每个成员变量都有自己的内存地址,可以通过对象的地址加上成员变量的偏移量来访问它们。
成员方法:
成员方法(也称为成员函数)存储在代码段(或称为文本段)中,而不是对象的内存空间中。成员方法只有一个实例,无论类的对象有多少个。这意味着,即使类的对象有很多个,它们共享相同的成员方法的代码。当调用成员方法时,会在堆栈上创建一个函数调用帧,其中包含方法的参数、局部变量和返回地址等信息。然后在堆栈上执行成员方法的代码。
所以当我们使用成员方法对自身成员对象进行访问、处理时,就需要使用到this指针这个隐含参数。
接着来说一下this指针的常见用法:
1.访问对象的数据成员:通过 this
指针可以访问对象的数据成员。
class RolePlayer {
public:
//设置角色姓名
void SetHP(char * NPCName) {
//this 访问对象的数据成员
this->m_NPCName = NPCName;
}
//获得角色姓名
char * GetName() {
return this->m_NPCName;
}
private:
char * m_NPCName;
int m_nHP;
};class RolePlayer {
public:
//设置角色姓名
void SetHP(char * NPCName) {
//this 访问对象的数据成员
this->m_NPCName = NPCName;
}
//获得角色姓名
char * GetName() {
return this->m_NPCName;
}
private:
char * m_NPCName;
int m_nHP;
};
在 SetHP
方法中,使用了 this
指针来访问对象的数据成员 m_NPCName
,以便将传入的姓名赋值给对象的 m_NPCName
成员变量。
在 GetName
方法中,同样使用了 this
指针来访问对象的数据成员 m_NPCName
,以便返回对象的姓名。
这样设计的好处是可以确保在成员方法中正确地访问对象的成员变量,而不会与其他对象的成员变量发生混淆。(this指针是非静态成员函数的隐含参数,在方法内调用成员变量时,编译器会默认加上this指针进行调用),自己在设计类的时候写上this指针能够增强代码的可读性
这个时候我们在主函数中创建两个对象:roleA 和 roleB;
int main{
//roleA
RolePlayer roleA;
char szRoleNameA[] = "Wolven";
roleA.SetName(szRoleNameA);
std::cout <<"Role A:"<< roleA.GetName() << std::endl;
//roleB
RolePlayer roleB;
char szRoleNameB[] = "WolvenBB";
roleB.SetName(szRoleNameB);
std::cout << "Role B:"<<roleB.GetName() << std::endl;
system("pause");
return 0;
}
这个时候我们分别给roleA和roleB两个对象设置名字,并让roleA和roleB分别调用GetName方法;最后对象roleA和roleB都分别获得对象自身的名称,而不会发生混淆。
返回对象本身:在成员函数中,可以使用 return *this;
来返回调用该函数的对象本身。
class RolePlayer {
public:
//设置角色姓名
void SetHP(char * NPCName) {
//this 访问对象的数据成员
this->m_NPCName = NPCName;
}
//获得角色姓名
char * GetName() {
return this->m_NPCName;
}
//获得对象本身
RolePlayer & GetObj() {
return * this;
}
private:
char * m_NPCName;
int m_nHP;
};
GetObj() 函数是 RolePlayer 类的一个成员方法,其目的是返回当前对象的引用。
返回类型:
GetObj()
函数的返回类型是RolePlayer &
,即返回一个RolePlayer
类型的引用。
函数实现:
在函数的实现中,使用
return *this;
来返回当前对象的引用。this
指针指向调用该函数的对象,因此*this
表示当前对象本身。
用途:
该函数通常用于获取当前对象的引用,并可以在其他地方使用该引用来访问和操作对象的成员变量和成员方法。
通过返回对象的引用而不是对象本身,可以避免不必要的复制开销,提高程序的效率。
例如,可以使用
GetObj()
函数来传递对象的引用给其他函数,以便在函数内部对对象进行操作。
在函数中进行调用
int main() {
RolePlayer roleA;
char szRoleNameA[] = "Wolven";
roleA.SetName(szRoleNameA);
std::cout <<"Role A:"<< roleA.GetName() << std::endl;
//获得对象之后再调用GetHP()方法
std::cout << "Role A:" << roleA.GetObj().GetHP() << std::endl;
system("pause");
return 0;
}
我们在代码中使用roleA.GetObj()函数获得对象的因引用后再使用GetName()函数也一样可以获得到对象的名字:
避免成员变量与局部变量冲突:当成员变量和局部变量同名时,可以使用 this
指针来区分。
考虑以下情况,我们想要在 SetName
方法中设置角色玩家的姓名,但同时也有一个局部变量叫做 m_NPCName
:
void SetName(char * m_NPCName) {
// 在此处,m_NPCName 是一个局部变量
// 但是我们也有一个成员变量叫做 m_NPCName
// 这可能会导致冲突
}
为了避免这种冲突,我们可以使用 this
指针来明确指示我们要操作的是成员变量,而不是局部变量。具体地,在上述的 SetName
方法中,this->m_NPCName` 明确指示我们要操作的是对象的成员变量,而不是局部变量。这样,就能够避免成员变量与局部变量之间的冲突。
void SetName(char * m_NPCName) {
this->m_NPCName = m_NPCName;
}
使用 this
指针的优势在于,它能够清晰地表明我们要访问的是成员变量,而不会与局部变量混淆。这样代码就更加清晰易读,且避免了潜在的错误。