说明
回顾:实例化的对象可以有不同的变量,但是调用的函数是完全相同的:
即,类对象中只保存成员变量,成员函数存放在公共的代码段。
成员函数最终会被编译成与对象无关的普通函数,所以编译时要在成员函数中添加一个额外的参数,把当前对象的首地址传入,以此来关联成员函数和成员变量,这个额外的参数就是this指针。
this是C++中的一个关键字,同时也是const指针。this指针指向当前对象,通过this指针可以访问当前对象的所有成员。
当前对象指正在使用的对象。举例来说,对于obj.print(); ,obj就是当前对象,this指针指向obj。
C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,
,让该指针指向当前对象(函数运行时调用该函数的对象)
在函数体中所有成员变量的操作,都是通过该指针去访问。
只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
this指针的特性
- this指针的类型:类类型* const
即,this指针本身不允许被改动(const在 * 之前修饰指向的内容,在 * 之后修饰指针本身) - 只能在“成员函数”的内部使用
- this指针本质上是一个成员函数的形参,对象调用成员函数时,将对象地址作为实参传递给this形参。
所以对象中不存储this指针。 - this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递(即,成员函数的第一个参数默认是隐含的this)。
因此,this作为关键字存在,调用和定义成员函数时不能显式使用this
但是在成员函数内部可以显式使用this,如cout<<this->year<<endl;
这里不写this编译器会加,自己写this也被允许↑(一般不会这样显式地写)
一般情况下this指针存在栈中,因为是形参。有些编译器会存到寄存器,如VS会放到寄存器中。
const成员函数与this指针
const修饰的成员函数称为const成员函数。
const修饰类成员函数,实际修饰的是该成员函数隐含的this指针,意味着在该成员函数中不能对类的任何成员进行修改。
class Date{
public:
void Display() const{
cout << _year << "/" << _month << "/" << _day << endl;
}
//相当于:
//void Display(const Date* this){
// cout << this->_year << "/" << this->_month << "/" << this->_day << endl;
//}
private:
int _year;
int _month;
int _day;
}
补充
delete this;
delete this语法上是可行的,只不过条件苛刻:
详见:Is it legal (and moral) for a member function to say delete this?
代码
#include<iostream>
using namespace std;
class Date {
public:
//void Init(Date* const this,int year,int month,int day)
void Init(int year,int month,int day) {
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
//常考题:
class A{
public:
void PrintA(){
cout << _a << endl;
}
void Show(){
cout << "Show()" << endl;
}
private:
int _a;
};
int main() {
Date d1;
d1.Init(2022, 2, 24);
//这样使用会否报错或崩溃或正常运行?
A* p = nullptr;
p->PrintA();
p->Show();
//正常运行。
//1.因为空指针的存在不是语法错误,空指针只在解引用时报错崩溃
//2.p调用成员函数不会出现空指针,因成员函数不保存在对象里
//3.这里p会被作为实参传给隐藏的this指针
return 0;
}