this指针
• Date类中有Init与Print两个成员函数,函数体中没有关于不同对象的区分,那当d1调⽤Init和 Print函数时,该函数是如何知道应该访问的是d1对象还是d2对象呢?那么这⾥就要看到C++给了⼀个隐含的this指针解决这⾥的问题
• 编译器编译后,类的成员函数默认都会在形参第⼀个位置,增加⼀个当前类类型的指针,叫做this指针。⽐如Date类的Init的真实原型为 void Init(Date* const this, int year, int month, int day)
this指针本身是不能被修改的,但是内容是可以修改的
• 类的成员函数中访问成员变量,本质都是通过this指针访问的,如Init函数中给_ year 赋值, this- >_year = year;
• C++规定不能在实参和形参的位置显⽰的写this指针(编译时编译器会处理),但是可以在函数体内显⽰使⽤this指针。
总之:C++编译器给每个"非静态的成员函数"增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
cpp
#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)
{
// 编译报错:error C2106: "=": 左操作数必须为左值
// this = nullptr;
// this->_year = year;
_year = year;//也可以写成上面这句代码,建议不加this
this->_month = month;
this->_day = day;
}
void Print()
{
cout << _year << "/" << _month << "/" << _day << endl;
}
private:
// 这⾥只是声明,没有开空间
int _year;
int _month;
int _day;
};
int main()
{
// Date类实例化出对象d1和d2
Date d1;
Date d2;
// d1.Init(&d1, 2026, 3, 1);
d1.Init(2026, 3, 1);
d1.Print();
// d2.Init(&d2, 2024, 7, 5);
d2.Init(2024, 7, 5);
d2.Print();
return 0;
}
测试
1.下⾯程序编译运⾏结果是()
A、编译报错 B、运⾏崩溃 C、正常运⾏
cpp
#include<iostream>
using namespace std;
class A
{
public:
void Print()
{
cout << "A::Print()" << endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->Print();//与普通函数一样,指针用->调用函数,相当于(*p).Print();
return 0;
}
答案选C
空指针或野指针是运行逻辑错误,编译错误是检查出语法错误,所以A错
如果函数体内没有访问任何成员变量(即不通过this指针访问数据成员),那么即使this指针为空,调用也可能成功,因为函数调用实际上是通过指针进行的(编译的时候在公共代码区中找到这个函数,只需要call函数地址就行),但函数本身并不解引用this指针。这里Print()函数只是打印一条消息,没有使用任何成员变量,所以它不会访问this指针指向的内存。
2.下⾯程序编译运⾏结果是()
A、编译报错 B、运⾏崩溃 C、正常运⾏
cpp
#include<iostream>
using namespace std;
class A
{
public:
void Print()
{
cout << "A::Print()" << endl;
cout << _a << endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->Print();
return 0;
}
答案选B
此程序崩溃是在Print()中,会隐含一个this->_a,而this指针是一个空指针,访问this指针_a的位置,就要对空指针进行解引用,此时就会崩溃
3.this指针存在内存哪个区域的()
A.栈 B.堆 C.静态区 D.常量区 E.对象⾥⾯
答案选A
this指针是个形参,形参是在函数的栈桢里,在函数的栈桢里面的变量是属于栈中的。
有时编译器会使用寄存器对其进行优化,因为this指针会被高频访问,此时this指针会存在寄存器中