构造函数的识别

来源:互联网 发布:mysql联合主键怎么设置 编辑:程序博客网 时间:2024/06/01 14:49

1.局部对象

    CNumber Number;00408F7D 8D 4D EC             lea         ecx,[Number]                 ;this指针的来源 对象的首地址00408F80 E8 AA B0 FF FF       call        CNumber::CNumber (040402Fh)  ;调用构造函数 先到跳转表
CNumber();栈操作00408900 55                   push        ebp  00408901 8B EC                mov         ebp,esp  00408903 81 EC CC 00 00 00    sub         esp,0CCh  00408909 53                   push        ebx  0040890A 56                   push        esi  0040890B 57                   push        edi  0040890C 51                   push        ecx  0040890D 8D BD 34 FF FF FF    lea         edi,[ebp-0CCh]  00408913 B9 33 00 00 00       mov         ecx,33h  00408918 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  0040891D F3 AB                rep stos    dword ptr es:[edi]  ;主体部分0040891F 59                   pop         ecx  00408920 89 4D F8             mov         dword ptr [this],ecx ;this指针始出面     {        m_nNumber = 1;00408923 8B 45 F8             mov         eax,dword ptr [this]  00408926 C7 00 01 00 00 00    mov         dword ptr [eax],1    ;这就很奇怪了哈 这是绕了两个弯啊 特征无疑    }0040892C 8B 45 F8             mov         eax,dword ptr [this] ;还有这里 完全是程式化的多此一举 0040892F 5F                   pop         edi  00408930 5E                   pop         esi  00408931 5B                   pop         ebx  00408932 8B E5                mov         esp,ebp  00408934 5D                   pop         ebp  00408935 C3                   ret  

2.堆对象

CNumber * pNumber = NULL;00408F7D C7 45 EC 00 00 00 00 mov         dword ptr [pNumber],0      pNumber = new CNumber[4];00408F84 6A 14                push        14h                       ;类的大小00408F86 E8 F8 A7 FF FF       call        operator new[] (0403783h)  00408F8B 83 C4 04             add         esp,4  00408F8E 89 85 FC FE FF FF    mov         dword ptr [ebp-104h],eax  ;保存new返回值的临时变量00408F94 C7 45 FC 00 00 00 00 mov         dword ptr [ebp-4],0       ;保存申请空间的次数00408F9B 83 BD FC FE FF FF 00 cmp         dword ptr [ebp-104h],0    ;判断堆空间是否申请成功00408FA2 74 3A                je          main+9Eh (0408FDEh)       ;失败则跳过构造函数;构造函数00408FA4 8B 85 FC FE FF FF    mov         eax,dword ptr [ebp-104h]  00408FAA C7 00 04 00 00 00    mov         dword ptr [eax],4  00408FB0 68 9B 3D 40 00       push        offset CNumber::~CNumber (0403D9Bh)  00408FB5 68 2F 40 40 00       push        offset CNumber::CNumber (040402Fh)  00408FBA 6A 04                push        4  00408FBC 6A 04                push        4  00408FBE 8B 8D FC FE FF FF    mov         ecx,dword ptr [ebp-104h]  00408FC4 83 C1 04             add         ecx,4  00408FC7 51                   push        ecx  00408FC8 E8 9C 8F FF FF       call        `eh vector constructor iterator' (0401F69h);堆对象代理函数; eh vector constructor iterator(pArrayAddress, sizeof(object),  object_count, ;pFunConstructor, pFunDestructor)其中 pFunDestructor为析构函数, pFunConstructor为构造函数,;object_count为对象数量, sizeof(object)为对象大小,pArrayAddress为起始地址。5个参数的函数并不多啊00408FCD 8B 95 FC FE FF FF    mov         edx,dword ptr [ebp-104h]      ;this指针00408FD3 83 C2 04             add         edx,4  00408FD6 89 95 C4 FE FF FF    mov         dword ptr [ebp-13Ch],edx  00408FDC EB 0A                jmp         main+0A8h (0408FE8h)  ;申请堆空间失败00408FDE C7 85 C4 FE FF FF 00 00 00 00 mov         dword ptr [ebp-13Ch],0  ;this指针倒啊倒00408FE8 8B 85 C4 FE FF FF    mov         eax,dword ptr [ebp-13Ch]      ;this指针00408FEE 89 85 08 FF FF FF    mov         dword ptr [ebp-0F8h],eax  00408FF4 C7 45 FC FF FF FF FF mov         dword ptr [ebp-4],0FFFFFFFFh  00408FFB 8B 8D 08 FF FF FF    mov         ecx,dword ptr [ebp-0F8h]  00409001 89 4D EC             mov         dword ptr [pNumber],ecx      pNumber->m_nNumber = 2;00409004 8B 45 EC             mov         eax,dword ptr [pNumber]   ;一个this指针传出花来了00409007 C7 00 02 00 00 00    mov         dword ptr [eax],2      printf("%d \r\n", pNumber->m_nNumber);0040900D 8B 45 EC             mov         eax,dword ptr [pNumber]  00409010 8B 08                mov         ecx,dword ptr [eax]  00409012 51                   push        ecx  00409013 68 14 C0 49 00       push        offset string "%d \r\n" (049C014h)  00409018 E8 9C AD FF FF       call        _printf (0403DB9h)  0040901D 83 C4 08             add         esp,8  

3.参数对象:
1.浅拷贝:如没有定义拷贝构造函数,编译器会对原对象与拷贝对象中的各数据成员直接进行数据复制,称为默认拷贝构造函数,属浅拷贝。

    CNumber one;004090EA 8D 4D D4             lea         ecx,[one]  004090ED E8 3D AF FF FF       call        CNumber::CNumber (040402Fh)  004090F2 C7 45 FC 02 00 00 00 mov         dword ptr [ebp-4],2      CNumber two(one);004090F9 8B 45 D4             mov         eax,dword ptr [one]  004090FC 89 45 C8             mov         dword ptr [two],eax  004090FF C6 45 FC 03          mov         byte ptr [ebp-4],3  

2.深拷贝

    CMyString MyString;00416273 8D 4D BC             lea         ecx,[MyString]  00416276 E8 4E DA FE FF       call        CMyString::CMyString (0403CC9h)  0041627B C6 45 FC 04          mov         byte ptr [ebp-4],4      MyString.SetString("Hello");0041627F 68 1C C0 49 00       push        offset string "Hello" (049C01Ch)  00416284 8D 4D BC             lea         ecx,[MyString]  00416287 E8 37 D1 FE FF       call        CMyString::SetString (04033C3h)      Show(MyString);0041628C 51                   push        ecx                                                   ;这里的作用是sub esp,4 主要因为MyString的类型长度为4 push ecx更短更快, 如果长度是其他值 ;这里是要变成 sub esp,sizeof(MyString)用来保存参数对象0041628D 8B CC                mov         ecx,esp                   ;保存参数对象的地址0041628F 89 A5 9C FE FF FF    mov         dword ptr [ebp-164h],esp  ;保存参数对象的地址00416295 8D 45 BC             lea         eax,[MyString]            ;取对象地址 00416298 50                   push        eax  00416299 E8 9E CB FE FF       call        CMyString::CMyString (0402E3Ch)  ;调用构造函数0041629E 89 85 94 FE FF FF    mov         dword ptr [ebp-16Ch],eax  004162A4 E8 D9 C1 FE FF       call        Show (0402482h)  004162A9 83 C4 04             add         esp,4  
CMyString(CMyString& obj){;栈操作00408800 55                   push        ebp  00408801 8B EC                mov         ebp,esp  00408803 81 EC E4 00 00 00    sub         esp,0E4h  00408809 53                   push        ebx  0040880A 56                   push        esi  0040880B 57                   push        edi  0040880C 51                   push        ecx  0040880D 8D BD 1C FF FF FF    lea         edi,[ebp-0E4h]  00408813 B9 39 00 00 00       mov         ecx,39h  00408818 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  0040881D F3 AB                rep stos    dword ptr es:[edi]  ;拷贝构造函数主体0040881F 59                   pop         ecx  00408820 89 4D F8             mov         dword ptr [this],ecx          int nLen = strlen(obj.m_pString);00408823 8B 45 08             mov         eax,dword ptr [obj]  00408826 8B 08                mov         ecx,dword ptr [eax]  00408828 51                   push        ecx          int nLen = strlen(obj.m_pString);00408829 E8 DD 95 FF FF       call        _strlen (0401E0Bh)  0040882E 83 C4 04             add         esp,4  00408831 89 45 EC             mov         dword ptr [nLen],eax          this->m_pString = new char[nLen + sizeof(char)];00408834 8B 45 EC             mov         eax,dword ptr [nLen]  00408837 83 C0 01             add         eax,1  0040883A 50                   push        eax  0040883B E8 43 AF FF FF       call        operator new[] (0403783h)  00408840 83 C4 04             add         esp,4  00408843 89 85 20 FF FF FF    mov         dword ptr [ebp-0E0h],eax  00408849 8B 4D F8             mov         ecx,dword ptr [this]  0040884C 8B 95 20 FF FF FF    mov         edx,dword ptr [ebp-0E0h]  00408852 89 11                mov         dword ptr [ecx],edx          strcpy(this->m_pString, obj.m_pString);00408854 8B 45 08             mov         eax,dword ptr [obj]  00408857 8B 08                mov         ecx,dword ptr [eax]  00408859 51                   push        ecx  0040885A 8B 55 F8             mov         edx,dword ptr [this]  0040885D 8B 02                mov         eax,dword ptr [edx]  0040885F 50                   push        eax  00408860 E8 05 96 FF FF       call        _strcpy (0401E6Ah)  00408865 83 C4 08             add         esp,8      }00408868 8B 45 F8             mov         eax,dword ptr [this]      ;返回this指针0040886B 5F                   pop         edi  0040886C 5E                   pop         esi  0040886D 5B                   pop         ebx  0040886E 81 C4 E4 00 00 00    add         esp,0E4h  00408874 3B EC                cmp         ebp,esp  00408876 E8 F4 9A FF FF       call        __RTC_CheckEsp (040236Fh)  0040887B 8B E5                mov         esp,ebp  0040887D 5D                   pop         ebp  0040887E C2 04 00             ret         4  
class CMyString{public:    CMyString(){        m_pString = NULL;    }    CMyString(CMyString& obj){        // 注:如在拷贝构造中这样拷贝指针,仍然属于浅拷贝,并没有拷贝指针所指向的        // 堆空间中的数据制作副本,仍然会造成错误。        // this->m_pString = obj.m_pString;        int nLen = strlen(obj.m_pString);        this->m_pString = new char[nLen + sizeof(char)];        strcpy(this->m_pString, obj.m_pString);    }    ~CMyString(){        if (m_pString != NULL)        {            delete [] m_pString;            m_pString = NULL;        }    }    void SetString(char * pString){        int nLen = strlen(pString);        if (m_pString != NULL)        {            delete [] m_pString;            m_pString = NULL;        }        m_pString = new char[nLen + sizeof(char)];        strcpy(m_pString, pString);    }    char * m_pString;};
0 0
原创粉丝点击