虽然一直知道this指针,但一直没有底层分析过,本节就分析一下C++中的this指针,彻底理解它的本质!!!
1、C语言中的结构体传参
C语言中结构体传参时建议使用指针,可以少了大量的内存复制
分析下面的C代码
//test.c
#include <stdio.h>
struct Student
{
int a;
int b;
int c;
};
int plus(struct Student* s)
{
return s->a + s->b + s->c;
}
int main()
{
struct Student s = {1, 2, 3};
int r = plus(&s);
printf("%d\n", r);//6
return 0;
}
①指针传参时是将结构体变量地址压栈,通过地址偏移直接获得该变量的各个成员
、
②而非指针传参,会有大量的内存拷贝,先提升堆栈,再将参数的值拷进去
2、C++中的this指针
C++引入封装的概念,可以将函数封装到结构体内部。
编译器将当前结构体变量的地址使用ecx寄存器作为参数传入成员函数,
当前结构体变量在使用成员函数时不需要额外传入当前结构体变量的地址。
//test.cpp
#include <stdio.h>
struct Student
{
int a;
int b;
int c;
int plus()
{
return a + b + c;
}
};
int main()
{
Student s = {1, 2, 3};
int r = s.plus();
printf("%d\n", r);//6
return 0;
}
①首先编译器会将对象的地址传入ecx寄存器,再调用函数
②在函数前言部分会将ecx的值取出放到this指针中,后面即可直接使用
上面截图在VS2015中直接写的是this,在VC++6.0中显示的是ebp-4或许更好理解一点,其实就是该函数一个局部的空间(变量),用来保存调用者的地址,当调用时通过ecx寄存器(通常)将调用者的地址传入该空间,以便后续操作,因此this也不会占用结构体的大小,this指针的作用域,生命周期一切都特别清晰了(纯属个人分析,只可参考)
所以上面的代码可以增加下面函数
void init(int a, int b, int c)
{
this->a = a; //使用隐含的this指针
this->b = b;
this->c = c;
}
plus函数也可修改
int plus(Student* const pThis)
{
if (this == pThis)
{
printf("this和pThis值相等,并且this的值就是在函数调用前后通过ecx传入对象的地址\n");
}
return pThis->a + pThis->b + pThis->c;
}
this指针相当于指针常量,不可运算,this完全可以被取代,而增加this的目的就是为了方便,也是C++设计的初衷。
当在成员函数中又调用其他成员函数:
通过以上分析,也可以理解静态成员函数不隐含this指针的原因,那么有人会问静态成员函数也可以用对象调用啊,我们可以看看
通过对象调用静态成员函数时,底层实际看不到那个对象,还直接类名::函数名()形式,也没有保存当前对象地址的行为。
关于静态成员函数参见另一篇文章:类的静态成员变量、静态成员函数
本节文章,纯属个人分析记录,几乎没有查阅资料,如有错误见谅,欢迎指正