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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kl1125290220/article/details/52235892

在今天进行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 ebp
00AE1461 mov ebp,esp
**00AE1463 sub esp,0F0h**
00AE1469 push ebx
00AE146A push esi
00AE146B push edi
00AE146C lea edi,[ebp-0F0h]
00AE1472 mov ecx,3Ch
00AE1477 mov eax,0CCCCCCCCh
00AE147C rep stos dword ptr es:[edi]
00AE147E mov eax,dword ptr ds:[00AE9000h]
00AE1483 xor eax,ebp
00AE1485 mov dword ptr [ebp-4],eax 

int n = 20;
00AE1488 mov dword ptr [n],14h
People i(30);
**00AE148F push 1Eh
00AE1491 lea ecx,[i]                                                                      
00AE1494 call People::People (0AE10EBh)**                         ;从这里我们可以知道,构造函数的调用是在编译阶段实现的。
People y(20);
00AE1499 push 14h
00AE149B lea ecx,[y]
00AE149E call People::People (0AE10EBh)

return 0;
00AE14A3 xor eax,eax
}

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

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

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

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

最后总结一下:

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

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


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

猜你喜欢

转载自blog.csdn.net/kl1125290220/article/details/52235892