概述
大家在定义类的过程中,有没有遇到过以下这种情况呢?
在这我们简单的定义一个类:
class Date
{
public :
void print()
{
cout <<_year<< "-" <<_month << "-"<< _day <<endl;
}
void init(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.init(2021,1,1);
d2.init(2021,1,2);
d1.print();
d2.print();
return 0;
}
我们可以看到,在Date类中有print与init两个成员函数,而在这两个成员函数中,没有任何关于对象的说明,那么这两个成员函数在执行时,是如何知道要对哪个对象进行操作的呢???
即当d1调用print函数时,该print函数是如何知道应该设置d1对象,而不是设置d2对象呢?
背后的原因是,C++中引入了this指针。
this指针:
C++编译器给每个“非静态的成员函数”增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
也就是说,原本未经编译器处理的代码应该是这样的:
class Date
{
public :
void print(/*Date*this*/)
{
cout <<this->_year<< "-" <<this->_month << "-"<<this-> _day <<endl;
}
void init(/*Date*this*/int year , int month , int day)
{
this-> _year = year;
this->_month = month;
this->_day = day;
}
private :
int _year ;
int _month ;
int _day ;
};
int main()
{
Date d1, d2;
d1.init(2021,1,1);//Date::init(&d1,2021,1,1)
d2.init(2021,1,2);//Date::init(&d2,2021,1,2)
d1.print();//Date::print(&d1)
d2.print();//Date::print(&d2)
return 0;
}
也就是说,编译器在编译代码时,会给每个成员函数添加一个隐藏的this指针,this指针指向调用该成员函数的对象,在成员函数内部,所有成员变量的访问都是通过this指针来访问的。
上述工作都是编译器自己进行实现,并不需要用户来操作,否则会导致编译失败。
我们可以进一步验证一下,查看一下this指针的指向,对象d1,d2的地址:(vs2019)
可以看到,上述关于this指针的描述是成立的。
this指针的特性:
1. this指针的类型:类类型* const
2. 只能在“成员函数”的内部使用 (主函数中使用时,编译器会报错)
3. this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this 形参。所以对象中不存储this指针。
4. this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。
this指针一般情况下都是通过exc寄存器进行传递,但也有例外。
这和调用约定有关,vs下普通成员函数调用约定都是_thiscall,以ecx寄存器进行参数传递。但也有_cdecl,这种调用约定就是通过参数压栈的方式进行传递。
this指针储存在哪里?
猜测一下,this指针是成员函数的一个隐藏参数,既然是参数,那就应该储存在栈上,如何验证呢?
//cout<<&this<<endl;编译错误,不能直接查看this指针的地址。
由于 this指针类型为:类类型*const,不能修改,所以直接查看this指针的地址显然不被允许,我们可以通过对this引用的方式来查看,然后通过比照this的地址,与esp(栈顶),ebp(栈底)的地址便可以知晓this是否在栈上。
通过验证,this指针存储在栈中。
this指针可以为空吗?
可以,当this指针为空是,若在成员函数中没有访问任何成员变量或成员函数则程序正常,反之则会崩溃。
最后
以上就是老迟到咖啡为你收集整理的C++------this指针篇的全部内容,希望文章能够帮你解决C++------this指针篇所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复