从汇编角度,清晰的去看构造函数和this指针到底是个什么东西呢?也许可以解决你的一点小疑问
首先写一个很简单的代码demo:
class A{
public:
int a;
A(){
;
}
void seta(int _a){
a=_a;
}
A* getA(){
return this;
}
};
int fun1(int px){
return px;
}
int main(){
A aa;
aa.seta(8);
aa.getA();
}

mov rbp, rsp:设置新的基址指针,指向当前栈帧。
mov QWORD PTR [rbp-8], rdi:将 this 指针(存储在 rdi 中)保存到栈上。
在seta中的部分汇编:
mov rax, QWORD PTR [rbp-8]:将 this 指针的值加载到 rax 中。
mov DWORD PTR [rax], edx:将 edx(即 _a 的值)存储到 this->a 中。
我们从类成员函数和构造函数中都能看到 两句关于参数的汇编,同理普通函数中px参数也有着相同的汇编,那么很显然,对于cpu而言,this指针仅仅是一个参数而已。C++语法糖对于this做了隐藏处理,因此我们在使用的时候才会无感。
而这个有这个this往往可以认为函数的完整使用是这样:
A aa;
aa.seta(8);
====
A::seta(&aa,8) 当然这么调用是错误的,看着很像类静态函数
this 指针的创建
- 函数调用前创建:当成员函数被调用时,
this指针在调用成员函数之前被设置为当前对象的地址。也就是说,在成员函数执行之前,this指针已经被创建并指向调用该函数的对象。
this 指针的销毁
- 函数调用结束后销毁:在成员函数执行完毕并返回后,
this指针的生命周期就结束了。因为this只是一个指向对象的指针,当函数返回时,不再需要这个指针,函数调用上下文会自动清理这个隐式参数。
学习C++的友友大概率会知道这么一句话:静态成员函数不属于类的某个具体对象,而是属于整个类。这意味着静态成员函数不能访问非静态成员变量和成员函数,因为它们没有 this 指针。针对这句话我们也可以通过cpu视角进行观察
而this 指针的存在条件
- 对象实例调用:只有当对象实例调用非静态成员函数时,
this指针才会被传递给该函数。 - 隐式参数:在非静态成员函数内部,编译器会自动添加一个隐式的
this指针参数,用于引用调用该函数的对象

观察上图,你就会看到 静态成员函数中没有this指针,即也就没法去调用相关的成员函数和数据,如果我们想要通过静态成员函数去调用对象相关的数据,可以通过黄色框框的这种写法。你会发现这种写法的汇编同成员函数的汇编相同,也就是说this存的就是传递进去的这个对象的地址。
也就有了成员函数的完整版应该是:void setp(A* this,int p);是不是看着参数和示例第二个静态成员函数一样~
cpu眼中构造函数与普通函数没有任何区别:

通过上面的汇编也能看明白,构造含有this指针,且对于cpu来说他与普通函数是相同的
派生类构造函数总会调用基类的构造函数

mov QWORD PTR [rbp-8], rdi:将this指针(在rdi中)保存到局部变量中。mov rax, QWORD PTR [rbp-8]:将this指针从局部变量中加载到rax中。mov rdi, rax:将this指针(现在在rax中)移动到rdi中,以便调用基类构造函数时使用。call A::A() [base object constructor]:调用基类A的构造函数。此时,this指针指向B对象,但调用的是A的构造函数,因此它会正确初始化A的部分。mov rax, QWORD PTR [rbp-8]:再次将this指针从局部变量中加载到rax中。mov DWORD PTR [rax+4], 1:将1赋值给this->a。这里的[rax+4]指的是b位于对象内偏移量 4 的位置。 (因为B继承A,B所以内存结构上,前四个字节是A.a ,然后才是B.a ,所以是移动到偏移4位置之后在赋值)



















