1.引出this指针
没有见过this指针的同学们看到这个地方,会忽然疑惑,this指针是什么个鬼东西,下面让我们来看一段类的定义与实例化的代码。
class Date
{
public :
void Display ()
{
cout <<_year<< "/" <<_month << "/"<< _day <<endl;
}
void SetDate(int year , int month , int day)
{
_year = year;
_month = month;
_day = day;
}
private :
int _year ;
int _month ;
int _day ;
};
int main()
{
Date d1, d2;
d1.SetDate(2018,5,1);
d2.SetDate(2018,7,1);
d1.Display();
d2.Display();
return 0;
}
我们在写C++类的时候,定义和对象的实例化都已经非常的熟悉了,但是在进行实例化的时候构造函数的传参只有要进行初始化的年月日等数据,以及我们在使用Display函数打印日期的时候居然没有传参。同学们有没有注意到,函数方法的定义不在类中,而在类外的一块公共区域,那么对象在调用方法的时候是怎么样进行区分的哪?
C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。可以认为在C++中每一个类内部的方法都含有this指针,通过this指针来区分辨别对象的。默认的this指针一直在程序中,所以我们不用手动加上。下面看一下基于上面的类,this指针展现的代码。
//类中的方法,在编译的过程中展开this指针
class Date
{
public :
void Display (Date* const this)
{
cout <<this->_year<< "/" <<this->_month << "/"<< this->_day <<endl;
}
void SetDate(Date* const this,int year , int month , int day)
{
this->_year = year;
this->_month = month;
this->_day = day;
}
private :
int _year ;
int _month ;
int _day ;
};
2.this指针的特性
- this指针的类型:类类型* const。因为我们只需要使用this指针指向的内容,而不能更改this指针的指向,所以用const修饰this指针更加的安全。
- 只能在“成员函数”的内部使用。调用成员函数时,不能显示传实参给this。定义成员函数时,也不能显示声明形参this。虽然因为在编译的阶段会自动加上this指针,如果你在将参数定义出来并进行传参会出现冲突,这是不允许的。
- this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
- this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递
- this指针存储在哪里?(面试经常问到)
一般都是在栈区,也有点在寄存器中。
6.this指针虽然是指针,但它是一个关键字。
3.this指针经典面试题
// 1.下面程序能编译通过吗?
// 2.下面程序会崩溃吗?在哪里崩溃
class A
{
public:
void PrintA()
{
cout<<_a<<endl;
}
void Show()
{
cout<<"Show()"<<endl;
}
private:
int _a;
};
int main()
{
A* p = nullptr;
p->PrintA();
p->Show();
}
1.下面程序能编译通过吗?
不能通过编译
2.下面程序会崩溃吗?在哪里崩溃
运行时会崩溃,在p->Show()处
3.分析
1)p虽然是空指针,但是p调用成员函数不会编译报错,因为空指针不是语法错误,编译器检查不出来。
2)p虽然是空指针,但是p调用成员函数页不会出现空指针访问。因为成员函数没有存在对象里面。
3)这里会把p当作实参传递给隐藏this指针。