构造函数的识别

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;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值