反汇编C++ OOP代码 分析构造函数如何被调用 以及简单的C++对象内存模型

来源:互联网 发布:gif压缩 知乎 编辑:程序博客网 时间:2024/05/02 04:54

在今天进行C++代码的思考时,产生一个疑问,就是C++类的构造函数是如何被调用的

于是就做了一个简单的实验来验证自己的想法。

//main.cpp#include <stdio.h>class People{private:int i;int b;public:People(int i){  this->i = i;  printf("This OOP addr is %p\n", this);}};int main(){int n = 20;People i(30);People y(20);return 0;}

然后我们将该代码进行反汇编,得到Mian函数的汇编代码如下

00AE1460 push ebp00AE1461 mov ebp,esp**00AE1463 sub esp,0F0h**00AE1469 push ebx00AE146A push esi00AE146B push edi00AE146C lea edi,[ebp-0F0h]00AE1472 mov ecx,3Ch00AE1477 mov eax,0CCCCCCCCh00AE147C rep stos dword ptr es:[edi]00AE147E mov eax,dword ptr ds:[00AE9000h]00AE1483 xor eax,ebp00AE1485 mov dword ptr [ebp-4],eax int n = 20;00AE1488 mov dword ptr [n],14hPeople i(30);**00AE148F push 1Eh00AE1491 lea ecx,[i]                                                                      00AE1494 call People::People (0AE10EBh)**                         ;从这里我们可以知道,构造函数的调用是在编译阶段实现的。People y(20);00AE1499 push 14h00AE149B lea ecx,[y]00AE149E call People::People (0AE10EBh)return 0;00AE14A3 xor eax,eax}

 

 

 

分析上面的代码,我们可以知道,
main函数一开始,首先进行的是一些通用的汇编模板,然后就是在栈中开辟了一个大小0xF0h的空间,
我们可以想到,这些空间就是用来存放局部变量的,而我们定义的两个对象也将存放在栈里面。
如果我们是用 new 来实例化对象的话,那么对象将不会被放在栈里面,而是放在了堆里面。

00AE148F push 1Eh00AE1491 lea ecx,[i]                                                                      00AE1494 call People::People (0AE10EBh)

从这三行代码,我们可以获得的信息有:

  • 构造函数的概念是在编译阶段是实现的
  • 实际传递给构造函数的参数有两个,一个就是我们定义的整形,一个就是名不见经传的this 也就是对象的地址
接下来我们去分析 People的汇编代码,就可以知道我们的分析是没有错的。在这里呢,我就偷懒不去分析多一次了。

最后总结一下:

C++的面向对象的思想和实现是在编译阶段实现的。
我们将他编译完之后,在运行阶段和C语言无区别。

C++类中函数,我推测它是存在于某个段中,而他的成员变量是存在于栈中或者是堆中。


本文为原创文章,转载请注明出处 Atqiao或 ***大呆书生***

0 0
原创粉丝点击