this指针
-
学习过C++面向对象的同学大概都知道,在一个类中,只有非静态成员变量是属于这个类对象的,而成员函数和静态成员都是只有一份的(换句话说,如果你实例化一个对象,那么成员函数是不会占用这个对象的内存空间的)
-
class Student { public: Student(){}; ~Student(){}; void setAge(int tmpAge){ age=tmpAge; } int getAge() { return age; } int age; }; int main() { Student s1,s2; s1.setAge(100); s2.setAge(30); return 0; }
-
对于上面这段代码来说,如果说成员函数只有一份,那么成员函数应该如何区分是哪个实例化对象调用的自己呢?
-
比如上面这个setAge函数,他并不知道是对象s1还是对象s2调用的自己
-
所以这时,this指针的概念就被引入了:当实例化一个对象时,就会自动产生一个this指针指向该对象,然后在调用函数时,编译器会隐式地将this指针传到那个非静态成员函数,从而让非静态成员函数知道是谁在调用自己
this指针使用时机
-
class Person { public: void setName(string name) { this->name = name; //这是this指针的一种用法,用于在形参和成员变量重名的时候,来实现区分 } Person& PersonAddPerson(Person p) //用于返回对象本身时候使用,这样可以实现链式编程 { this->age += p.age; //返回对象本身 return *this; } private: string name; }; int main() { Person p1; p1.setName("Tom"); Person p2(10); //链式编程思想 p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1); cout << "p2.age = " << p2.age << endl; return 0; } //对于上面这段代码p.setName("Tom")来说,编译器会看成是这样:p.setName(&p, "Tom");
-
上面这段代码很好的展示了this指针的使用场景,最常用的就是以上两个场景
-
你会发现当使用到==“对象自身”的语义时,你就会想到使用this指针来指代对象自身==
-
this其实就是指向对象的一个指针,就像上面的最后一行注释写的那样,编译器在发现你调用某个非静态成员函数时,会隐式地传入对象自身的地址,并且在每个非静态成员函数的参数列表中加上一个该类的指针叫做this,这些都是你不可见的
this指针注意事项
注意1:this指针只针对非静态成员函数有效
-
this指针只针对非静态成员函数有用,对于静态成员函数则不起作用
-
这是因为静态成员函数与某个对象无关,它是属于整个类的,所有对象共用一个静态成员函数
-
这个静态成员函数在你对象实例化出来之前就已经存在了,而this指针是随着对象的实例化而出现的,所以静态成员函数不可以使用this指针(你可以把它理解为根本没有指针传入),请看下面这个例子
-
class Person { public: void ShowClassName() { cout << "我是Person类!" << endl; } void ShowPerson() { cout<<"this指针所放的地址为:"<<this<<endl; } static void func() { cout<<this->mAge<<endl; } public: int mAge; };
-
编译时会出错,报错如下:
-
test.cpp: In static member function 'static void Person::func()': test.cpp:15:15: error: 'this' is unavailable for static member functions 15 | cout<<this->mAge<<endl; |
注意2:注意this有可能是空指针
class Person {
public:
Person() {
cout<<"这是Person类的构造函数"<<endl;
}
~Person() {
cout<<"这是Person类的析构函数"<<endl;
}
void ShowClassName() {
cout << "我是Person类!" << endl;
}
void ShowPerson() {
cout<<"this指针所放的地址为:"<<this<<endl;
}
static void func() {
cout<<"静态成员函数"<<endl;
}
public:
int mAge;
};
void test01()
{
Person * p = NULL;
p->ShowPerson(); //注意,空指针是可以调用成员函数的
p->func(); //同样的,也可以调用静态成员函数
}
- 对于这个test函数中的p来说,其实p本身就可以看做是一个this指针,都指向这个实例化的对象,只不过这个实例化是nullptr,所以this指针的值也是nullptr
- 我一开始会想:这个对象根本就为空,不存在,为啥可以通过指针调用函数呢?其实前面已经说过答案了,这些函数其实都本不属于这个类本身,所以其实是否实例化对象都不是很重要,函数就在那里,只不过区别是传入的this指针是不是nullptr的区别罢了
- 但是需要注意的是,使用一个为空的this指针时,需要特别注意判断为空,否则容易发生非法操作
this指针小测验
- 希望大家可以通过这个小测验来更好地理解this指针
开始咯!!!
- 什么是this指针?它有什么作用?
- 答:this指针是一个指向当前对象的指针,在每个非静态成员函数中都被隐式地传递给函数。它的作用是让成员函数能够访问该对象的成员变量和成员函数。
- 如何在C++中使用this指针?
- 答:在C++中,可以使用this关键字来访问该指针。例如,可以使用this->成员变量名来访问对象的成员变量。在成员函数中,可以使用this指针来避免参数名和成员变量名相同的冲突,或者用于返回自身。
- 在成员函数中,this指针可以被显示调用吗?为什么?
- 答:在成员函数中,this指针可以被显式调用,但是不推荐这样做。因为this指针在每个非静态成员函数中都被隐式地传递给函数,所以不需要显式地使用它。如果需要显式地使用this指针,可能会导致代码可读性降低,增加出错的可能性。
- 静态成员函数中是否有this指针?为什么?
- 答:静态成员函数中没有this指针。因为静态成员函数是属于类而不是属于对象的,所以它没有this指针。在静态成员函数中不能访问非静态成员变量和非静态成员函数,只能访问静态成员变量和静态成员函数。
- this指针是否占用对象的存储空间?
- 答:可以通过sizeof验证,this指针是不占用对象的,它是编译器自动为我们产生的,不在类的内部