我们可以从以下三方面来认识this指针:
一.为什么会产生this指针??
二.this指针的特点。
三.__thiscall的调用方式
四.问题
一。为什么会产生this指针???
class Box
{
public:
int volume(int height, int width, int length)
{
return height*width*length;
}
private:
};
int main()
{
Box t1, t2, t3;
t1.volume(2, 4, 5);
t2.volume(3, 6, 9);
t3.volume(7, 8, 9);
system("pause");
return 0;
}
我们可以从上边代码看出,定义了三个对象t1,t2,t3再调用时他们是如何区分自身的height,width,length这时候就需要他们各自的this指针来完成。在调用时系统会把对象t1的起始地址赋给this指针,于是在成员函数引用数据成员时,就按照this的指向找到各自对应的数据成员。(这里可以从反汇编中更好的理解)
从反汇编理解this指针:https://blog.csdn.net/jxz_dz/article/details/47808795
由此,我们得出结论 : 将全局的函数放进结构体内,便出现了this指针,该this指针是由ecx传递的 . 更重要的是这是编译器替我们加上的.
即是说,由C转化为C++,更多的是编译器做的操作.
可以归纳this指针的本质 :
this是调用结构体(或类)内部成员函数时传递的参数(通常用ecx传递) . 其本质是结构体变量(或者对象)的第一个成员变量的地址.
二.this指针的特征:
- this指针的类型:类类型*const
- this指针的地址寄存在ecx中
- this指针并不是对象本身的一部分,不影响sizeof的结果
- this的作用域在类“成员函数”的内部
- this指针是类“成员函数”的第一个默认隐含参数,编译器自动维护传递,类编写者不能显式传递
- 只有在类的非静态成员函数中才可以使用this指针,其他任何函数都不允许
- this指针不可以++ - -操作 , 即this指针的值不可以被改变 .
- .参数个数确定的函数,this指针是由ecx传递的 , 在变参函数中最后一个传递的参数是this指针
三.__thiscall的调用方式
class Box
{
public:
int volume(int height, int width, int length)
{
return height*width*length;
}
private:
};
int volume(int height, int width, int length)
{
return height*width*length;
}
int main()
{
Box t1, t2;
t1.volume(2, 4, 5);
t2.volume(3, 6, 9);
volume(1, 2, 3);
system("pause");
return 0;
}
从上边的代码和反汇编我们可以看出__thiscall的调用特点:
- 参数的传递顺序:从右向左
- 参数的传递方式:是利用栈传递
- 堆栈平衡:调用者平衡堆栈(外平栈)
- __thiscall只能够用在类的成员函数上
- 如果参数个数确定,this指针通过ecx传递给被调用者;如果参数不确定,this指针在所有参数被压栈后压入栈堆
- 对参数个数不确定的,调用者清理堆栈,否则函数自己清理堆栈
四.问题
1.引用底层的是指针,此处为什么不是引用,而是this指针???
因为this指针出现的时间比引用早所以用this指针
2.this指针可以为空吗??
#include<iostream>
#include<Windows.h>
using namespace std;
class MyClass
{
public:
void show()
{
//this指向的就是该函数的地址(正在调用时的成员函数所在对象的起始地址)(寄存在ecx中)
cout << this << endl;
}
private:
};
int main()
{
//this指针也可以为空
MyClass* t = NULL;
t->show();
system("pause");
return 0;
}
从上边代码以及运行的结果可以知道:this指针可以为空!!!
this指针关于delete的问题: