我们先看下面代码
class Data
{
private:
int _year;
int _month;
int _day;
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << " - " << _month << " - " << _day << endl;
}
};
int main()
{
Data D1;
D1.Init(2023, 4, 2);
D1.Print();
Data D2;
D2.Init(2023, 5, 2);
D2.Print();
return 0;
}
[点击并拖拽以移动]
我们可以知道的是创建D1,和 D2 两个对象 ,他两的成员变量在内存空间是独立的(在各自的类中)
但是在调用的 Init 和Print 两个成员函数是不在类里的,是在类外一块公共区域
运行结果 -- 将D1 和 D2 分别的打印出来
问题来了 -- D1和D2 对象都调用了Print 和 Init 成员函数 编译器是怎么分析出是初始化D1还是D2 , 是打印D1和D2的呢
这就引出了我们接下来要了解的this 指针
1.this指针是隐藏指针
怎么隐藏的呢
以Print函数为例 void Print(Data*this) , 不显示出来
void Print(&D1) 传参给Print 函数
底层的初始化和打印就通过this指针来进行 -- 如下
这样子我们编译器就通过this指针 ,完美的区分了D1和D2调用同一块区域上的同一个成员函数了
我们在使用this指针也有需要注意的地方
1.在调用成员函数时,不能显示传实参给this
2.在定义成员函数时,也不能显示声明形参this
3.在成员内部是可以显示,使用this 就是上图的使用方法
我们学完了this指针的用法 -- > 我们来解释下面的两道题目
为什么编译器不编译错误,并且能正常运行呢
class A
{
public:
void Show()
{
cout << "Show()" << endl;
}
private:
int _a;
};
int main()
{
A*p = nullptr;
p->Show();
return 0;
}
A*p=nullptr 将p设成空指针了 为什么p->Show()不会出现空指针访问的问题呢,并且不出现编译错误的问题勒
原因是因为 : 空指针调用成员函数,又不是语法问题,使用编译器不报错
空指针调用函数成员不出现访问问题的原因是空指针指向的成员函数又不在对象中
p->Show转换成了一条call指令,去类外的区域找Show函数
这段代码又为什么却出现崩溃的情况呢
class A
{
public:
void Print()
{
cout << _a << endl;
//此时this是空指针
//this->_a
//程序崩溃
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->Print();
return 0;
}
原因是因为 cout<< _a<<endl; 是本质是this->_a ,但是此时我们的this是空指针了,Print(p)
出现了空指针的访问问题。