关于this指针
大家好,我是芒果,一名非科班的在校大学生。对C/C++、数据结构、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流
作者简介:
- CSDN C/C++领域新星创作者https://blog.csdn.net/chuxinchangcun?type=blog
- 掘金LV3用户 https://juejin.cn/user/1381426159953960
- 阿里云社区专家博主,星级博主,技术博主 https://developer.aliyun.com/profile/expert/5lkdbuggiiuhc
- 华为云云享专家 https://bbs.huaweicloud.com/community/myhomepage
8.this指针
8.1 this指针的引出
我们先来定义一个日期类Date
对于上述类,有这样的一个问题: Date类中有两个成员函数,函数体中没有关于不同对象的区分,那当d1调用函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?
C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参 数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该 指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
class Date
{
public:
//void Init(Date* this,int year, int month, int day)
void Init(int year, int month, int day)
{
_year = year;//this->_year = year;
_month = month;//this->_month = month;
_day = day;//this->_day = day;
}
//void Print(Date* this)
void Print()
{
//cout << this->_year << "-"<<this->_month << "-" <<this-> _day << endl;
cout << _year << "-"<<_month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
d1.Init(2022, 1, 16); //d1.Init(&d1,20221,1,16);
d1.Print();//d1.Print(&d1);
Date d2;
d2.Init(2022, 1, 17); //d1.Init(&d2, 20221, 1, 17);
d2.Print();//d2.Print(&d2);
return 0;
}
隐藏了this指针。
-
1.调用成员函数时:不能显示传实参给this
d1.Init(&d1,2022,1,16);//err d1.Init(2022,1,16);//OK
-
2.定义成员函数时,也不能显示声明形参this
void Print(Date* this)//err void Print()//ok
-
3.在成员函数内部,我们可以显示使用this
void Print() { cout << this->_year << "-"<<this->_month << "-" <<this-> _day << endl;//OK cout << _year << "-"<<_month << "-" << _day << endl;//ok }
this作为一个关键字存在
8.2 this指针的特性
- this指针的类型:类型 const*(即this指针不能修改) Date* const this this指向的内容可以修改
- 只能在“成员函数”的内部使用
- this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this 形参。所以对象中不存储this指针。
- this指针是成员函数第一个隐含的指针
形参
,一般情况由编译器通过ecx寄存器自动传递,不需要用户 传递
【面试题】
-
this指针存在哪里?
this指针既然是形参,那么它存在栈中,有些编译器会把它放到寄存器中,如:vs2013和vs2019放在ecx寄存器中
-
this指针可以为空吗?
要看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->Show();
p->PrintA();
}
注意:编译检查不出空指针问题,编译器只能检查出语法错误。空指针不是语法错误,是运行时错误。
上述代码没有语法错误,所以肯定能编译通过。
分析:
调用成员函数是call一个地址去访问,空指针不解引用不会报错。传参时,也可以传空指针!
- 点赞
- 收藏
- 关注作者
评论(0)