c++构造函数的背后

OS winxp 、平台:i386

/*

* 以下是测试代码

*/

/*


* class obj 
*/
class obj
{
public:
     int m_i;
     int *m_pi;
     obj(int *ptemp)
     {

        printf("this point to %x/n" , (unsigned int)this );
        m_i = 0;
        printf("address of m_i = %x/n" , (unsigned int)&m_i );
        this->m_pi = ptemp;
        printf("address of m_pi = %x/n" , (unsigned int)&m_pi);
     }
     void funcA()
    {
         printf("this is funcA/n");
    }
 
    void funcB()
   {
        printf("this is funcB/n");
   }
   virtual void vfunc()
   {
        printf("this is virtual func");
   }
   ~obj()
   {
   }
};

/* main */

  int main(int arg , char *argv[])

  {

  int n = 2 ;
  obj *po = new obj(&n);
  cout<<"***after construt***"<<endl;
  printf("address of po = %x " , (unsigned int)po );
  cout<<po->m_i<<endl;
  cout<<*po->m_pi<<endl; 
  delete po ;

}

1.初始化过程:

我们知道类的对象初始化需要调用类的构造函数。那么这个过程是怎么样的呢?我们先来看看对象的初始化过程。 

(一) obj *po new obj(&n) ;

对应汇编:

00401C 23 0F BF 0D 5C 55 41 00    movsx       ecx,word ptr [`main'::`2'::__LINE__Var ( 0041555c )]

00401C 2A 83 C 1 11                         add         ecx,11h

00401C 2D 51                                   push        ecx

00401C 2E 68 20 55 41 00             push        offset THIS_FILE (00415520)

00401C 33 6A 0C                               push        0Ch

00401C 35 E8 80 FB FF FF              call        operator new (004017ba)/*1 调用operator newnew操作符)分配了sizeof(obj)大小的内存空间。*/

00401C 3A 83 C 4 0C                         add         esp,0Ch

00401C 3D 89 45 E0                         mov         dword ptr [ebp-20h],eax    /*2.eax中保存了返回的内存起始地址指针,此处把起始地址指针保存在[ebp-20h]中。现在我们记住eax的值,我这里是0x00421110,后面有用*/

00401C 40 C 7 45 FC 00 00 00 00    mov         dword ptr [ebp-4],0

00401C 47 83 7D E0 00                   cmp         dword ptr [ebp-20h],0    /*3 这里判断分配的地址是否为空,和我们通常在分配完内存后所作的判断一样*/

00401C 4B 74 11                              je          main+12Eh ( 00401c 5e)

00401C 4D 8D 55 EC                       lea         edx,[n]

00401C 50 52                                  push      edx    /*obj的构造函数的参数入栈,为调用构造函数作准备*/

00401C 51 8B 4D E0                       mov       ecx,dword ptr [ebp-20h]

/*参数保存在寄存器cx*/

00401C 54 E8 D 4 F 3 FF FF            call        @ILT+40(obj::obj) (0040102d) /*呵呵,开始了。进入obj构造函数的调用*/

 我们仍然来看能给我们提示的关键语句:

(二)printf("this point to %x/n" , (unsigned int)this );

00401A 91 8B F4                             mov         esi,esp

00401A 93 8B 55 FC                        mov         edx,dword ptr [ebp-4]

00401A 96 52                                   push        edx

00401A 97 68 6C 41 41 00               push        offset string "this point to %x/n" ( 0041416c )

/*按函数调用方式__cdecl ,参数(unsigned int)this)先入栈,在我这里,从memory中可以看到ebp-4 = 12fee4 ,[ebp-4] = 421110 ,这就是前面通过operator new分配的内存首址,也就是说obj *po此时指向的地址。在obj的构造函数里,obj *po完成一系列的初始化工作。*/

00401A 9C FF 15 D4 62 41 00         call        dword ptr [__imp__printf (004162d4)]

00401AA2 83 C 4 08                         add         esp,8

00401AA5 3B F4                              cmp         esi,esp

00401AA7 E8 26 FD FF FF              call        _chkesp (004017d2)

    从以上分析我们可以看出,obj *po首先由operator new分配内存地址,然后以内存地址作为参数调用obj构造函数,也就是说在调用构造函数以前,对象的内存布局就已经完成.基本上我们的分析到这里就可以结束了.对于c++构造函数背后做的事我们也可以有一个比较清晰的认识了吧!

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值