分享

图文并茂从汇编层理解Cthis指针实现原理

 山峰云绕 2021-02-03

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

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多