图文并茂从汇编层理解Cthis指针实现原理
https://m.toutiao.com/is/JTLB9W7/
当我们在C++中定义一个类时,编译器会把C++代码编译成汇编,但汇编中并没有类、类成员函数、类成员变量等概念,那在汇编层是如何来处理类的呢?
下面我们来看个简单例子:
class TestClass{public: int Sum() { return m_a+m_b; }public: int m_a; int m_b;};int main(){ TestClass testClassObj; testClassObj.m_a = 5; testClassObj.m_b = 6; int result = testClassObj.Sum(); return 0;}
编译器会把上面的代码生成,语义类似下面的C代码
struct TestClass{ int m_a; int m_b;};INT TestClass_Sum(TestClass* this){ return this->m_a + this->m_b; }int main(){ TestClass testClassObj; testClassObj.m_a = 5; testClassObj.m_b = 6; int result = TestClass_Sum(&testClassObj); return 0;}
虽然C++中TestClass类把成员变量与成员函数写在了一起,但经过编译器处理后,本质上还是分开的,编译器会为成员函数(Sum函数)添加一个形参(this指针),通过这个this变量就能访问类对象里的成员变量。
下面来看下C++的类成员函数Sum是不是多了个形参this指针,且this指针指向对象本身:
我们前面详细分析过,函数的局部变量保存在栈上,
(1)testClassObj是main函数的局部变量,所以testClassObj保存在函数的栈上,而m_a是testClassObj对象的第一个局部变量,所以m_a的地址等于testClassObj对象的地址,
movl $0x5,-0x10(%rbp) 等价于 m_a=5;
movl $0x6,-0xc(%rbp) 等价于 m_b=5;
从而可知testClassObj的地址为-0x10(%rbp),从图中
可知,testClassObj的地址,最后被传到了sum函数的栈上,保存的地址为$rbp-0x8,但Sum()函数的定义里是没有带形参的,所以这个新传入的对象就是编译器给我们加上的this指针,指向对象本身。这样就从汇编层证实了,编译器确实给类的成员函数添加了一个形参this指针。
赞 (0)