C++中的类与C语言中的结构体有很多的相似的地方,可以说本质上除了结构体只能定义成员变量,以及结构体默认的访问控制权限是public之外与class没啥区别。但是结构体变量每次调用函数的时候需要指针,而类中的成员函数明明被保存在公共代码段,他们调用的也是同一个函数,对象调用函数却不用传指针也能精准对对象的数据成员进行操作,其实是编译器默默承担了这一切。编译器自动地生成了一个this指针,作为成员函数的一个参数...
一、什么是this指针?
this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行。全局仅有一个this指针,当一个对象被创建时,this指针就存放指向对象数据的首地址。
二、放入代码中理解
在正常创建类和实例化对象时我们是这样做的:
class date
{
public:
date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void print_d()
{
cout << _year << "年" << _month << "月" << _day << "日" << endl;;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
date d1(2024, 7, 17);
date d2(2024, 7, 18);
d1.print_d();
d2.print_d();
return 0;
}
实际上编译器对成员函数和对象调用函数做了以下的改变(粗体的部分):
this指针的相关形参和实参是不能显示着写的(背景为绿色的部分),但是在类里面可以显示着使用(背景为蓝色的部分)
date(date* const this, int year, int month, int day)
{
this->_year = year;
this->_month = month;
this->_day = day;
}
void print_d(date* const this)
{
cout << this->_year << "年" << this->_month << "月" << this->_day << "日" << endl;
}date d1(&d1, 2024, 7, 17);
date d2(&d2, 2024, 7, 18);d1.print_d(&d1);
d2.print_d(&d2);
以上表达式中 this->_year= year; 和 (*this)._year = year; 以及 _year = year; 是一样的,初期的时候可以在类里将this直接写出来方便自己理解,后期可以直接省略。(此时也能表明类的成员变量要有特定表示比较好,_year和year更直观便捷) 。
三、this指针小知识
1.this指针存放在哪里?
指针是形参,存在栈帧上,vs下存到ecx寄存器中。
2.this指针的类型
CLASS* const this (const在*后修饰的是指针,在*前修饰的是指针指向的对象) 这意味着this指针是不能修改的,它不能显示着写,所以也不存在修改一说。
3.关于this指针的小题目
(下列程序会有怎样的运行结果?)
class A { public: void Print() { cout << "Print()" << endl; } private: int _a; }; int main() { A* p = nullptr; p->Print(); return 0; }
👆这个程序其实是会正常运行的,虽然this指针为空,但是Print()函数并没有使用到this指针,所以也没有出问题。
class A { public: void PrintA() { cout << _a << endl; } private: int _a; }; int main() { A* p = nullptr; p->PrintA(); return 0; }
👆而这个程序就会运行崩溃(还是能通过编译的如果出现了p->_a = 1;这种直接空指针访问了对象成员变量会不能编译通过报错),因为this指针被使用了,但它是一个空指针。(当然,每个编译器不一样,在这个问题上也可能会有不同的结果出现随机值,正常运行(编译器优化)都是有可能的)
-The End-