C++对象继承

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

windows下,vs2017
C++代码:
1、类中没有虚函数:

class Base
{
public:
    int x=1;
    int b=2;
    Base()
    {
        x = 3;
        b = 4;
    }
    void b_test1()
    {
        printf("b_test1\n");
    }
};

class Sub:Base
{
public:
    int x=10;
    int b=11;
    int c=12;
    Sub()
    {
        x = 21;
        b = 22;
        c = 23;
    }
    void b_test1()
    {
        printf("sub_test1\n");
    }
};

int main()
{
    Sub sub;
    return 0;
}

反汇编代码:

    Sub sub;
00BC1818 8D 4D E4             lea         ecx,[sub]            //sub变量地址传给ecx
00BC181B E8 CB F8 FF FF       call        Sub::Sub (0BC10EBh)  

Sub::Sub:
00BC10EB E9 60 06 00 00       jmp         Sub::Sub (0BC1750h) 

    Sub()
00BC1750 55                   push        ebp  
00BC1751 8B EC                mov         ebp,esp  
00BC1753 81 EC CC 00 00 00    sub         esp,0CCh         //分配栈空间
00BC1759 53                   push        ebx  
00BC175A 56                   push        esi  
00BC175B 57                   push        edi  
00BC175C 51                   push        ecx              //把sub地址压栈
00BC175D 8D BD 34 FF FF FF    lea         edi,[ebp-0CCh]   
00BC1763 B9 33 00 00 00       mov         ecx,33h  
00BC1768 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
00BC176D F3 AB                rep stos    dword ptr es:[edi]  //栈空间数据初始化
00BC176F 59                   pop         ecx                 //sub地址出栈
00BC1770 89 4D F8             mov         dword ptr [this],ecx  //把sub地址付给this指针。
00BC1773 8B 4D F8             mov         ecx,dword ptr [this]  //this指针传给ecx
00BC1776 E8 B7 F8 FF FF       call        Base::Base (0BC1032h) //调用基类的构造函数

Base::Base:
00BC1032 E9 A9 06 00 00       jmp         Base::Base (0BC16E0h) 

    Base()
00BC16E0 55                   push        ebp  
00BC16E1 8B EC                mov         ebp,esp  
00BC16E3 81 EC CC 00 00 00    sub         esp,0CCh  
00BC16E9 53                   push        ebx  
00BC16EA 56                   push        esi  
00BC16EB 57                   push        edi  
00BC16EC 51                   push        ecx  
00BC16ED 8D BD 34 FF FF FF    lea         edi,[ebp-0CCh]  
00BC16F3 B9 33 00 00 00       mov         ecx,33h  
00BC16F8 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
00BC16FD F3 AB                rep stos    dword ptr es:[edi]  
00BC16FF 59                   pop         ecx                   //子类this指针出栈,存放到ecx中
00BC1700 89 4D F8             mov         dword ptr [this],ecx  //将子类的this指针赋给基类的this指针。

class Base
{
public:
    int x=1;
00BC1703 8B 45 F8             mov         eax,dword ptr [this]    
00BC1706 C7 00 01 00 00 00    mov         dword ptr [eax],1     类成员数据初始化
    int b=2;
00BC170C 8B 45 F8             mov         eax,dword ptr [this]  
00BC170F C7 40 04 02 00 00 00 mov         dword ptr [eax+4],2  
    {
        x = 3;
00BC1716 8B 45 F8             mov         eax,dword ptr [this]    //基类构造函数,修改成员变量的值。
00BC1719 C7 00 03 00 00 00    mov         dword ptr [eax],3  
        b = 4;
00BC171F 8B 45 F8             mov         eax,dword ptr [this]  
00BC1722 C7 40 04 04 00 00 00 mov         dword ptr [eax+4],4  

    }
00BC1729 8B 45 F8             mov         eax,dword ptr [this]  
00BC172C 5F                   pop         edi  
00BC172D 5E                   pop         esi  
00BC172E 5B                   pop         ebx  
00BC172F 8B E5                mov         esp,ebp  
00BC1731 5D                   pop         ebp  
00BC1732 C3                   ret  

class Sub:Base
{
public:
    int x=10;
00BC177B 8B 45 F8             mov         eax,dword ptr [this]  
00BC177E C7 40 08 0A 00 00 00 mov         dword ptr [eax+8],0Ah //子类成员变量初始化,注意成员变量的地址
    int b=11;
00BC1785 8B 45 F8             mov         eax,dword ptr [this]  
00BC1788 C7 40 0C 0B 00 00 00 mov         dword ptr [eax+0Ch],0Bh  
    int c=12;
00BC178F 8B 45 F8             mov         eax,dword ptr [this]  
00BC1792 C7 40 10 0C 00 00 00 mov         dword ptr [eax+10h],0Ch  
    {
        x = 21;
00BC1799 8B 45 F8             mov         eax,dword ptr [this]  
00BC179C C7 40 08 15 00 00 00 mov         dword ptr [eax+8],15h //子类构造函数修改子类成员变量的值。 
        b = 22;
00BC17A3 8B 45 F8             mov         eax,dword ptr [this]  
00BC17A6 C7 40 0C 16 00 00 00 mov         dword ptr [eax+0Ch],16h  
        c = 23;
00BC17AD 8B 45 F8             mov         eax,dword ptr [this]  
00BC17B0 C7 40 10 17 00 00 00 mov         dword ptr [eax+10h],17h  
    }
00BC17B7 8B 45 F8             mov         eax,dword ptr [this]  
00BC17BA 5F                   pop         edi  
00BC17BB 5E                   pop         esi  
00BC17BC 5B                   pop         ebx  
00BC17BD 81 C4 CC 00 00 00    add         esp,0CCh  
00BC17C3 3B EC                cmp         ebp,esp  
00BC17C5 E8 5D F9 FF FF       call        __RTC_CheckEsp (0BC1127h)  
00BC17CA 8B E5                mov         esp,ebp  
00BC17CC 5D                   pop         ebp  
00BC17CD C3                   ret 

    return 0;
00BC1820 33 C0                xor         eax,eax  
}

2、类中包含虚函数:

class Base
{
public:
    int x=1;
    int b=2;
    Base()
    {
        x = 3;
        b = 4;
    }
    virtual void b_test1()
    {
        printf("b_test1\n");
    }
};

class Sub:Base
{
public:
    int x=10;
    int b=11;
    int c=12;
    Sub()
    {
        x = 21;
        b = 22;
        c = 23;
    }
    virtual  void b_test1()
    {
        printf("sub_test1\n");
    }
};


int main()
{
    Sub sub;
    return 0;
}

反汇编:

int main()
{
01041A30 55                   push        ebp  
01041A31 8B EC                mov         ebp,esp  
01041A33 81 EC E4 00 00 00    sub         esp,0E4h  
01041A39 53                   push        ebx  
01041A3A 56                   push        esi  
01041A3B 57                   push        edi  
01041A3C 8D BD 1C FF FF FF    lea         edi,[ebp-0E4h]  
01041A42 B9 39 00 00 00       mov         ecx,39h  
01041A47 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
01041A4C F3 AB                rep stos    dword ptr es:[edi]  
01041A4E A1 00 A0 04 01       mov         eax,dword ptr [__security_cookie (0104A000h)]  
01041A53 33 C5                xor         eax,ebp  
01041A55 89 45 FC             mov         dword ptr [ebp-4],eax  
    Sub sub;
01041A58 8D 4D E0             lea         ecx,[sub]                     
01041A5B E8 A9 F6 FF FF       call        Sub::Sub (01041109h)     //断点到此处:
    return 0;
01041A60 33 C0                xor         eax,eax  
}

Sub::Sub:
01041109 E9 F2 06 00 00       jmp         Sub::Sub (01041800h) 

    Sub()
01041800 55                   push        ebp  
01041801 8B EC                mov         ebp,esp  
01041803 81 EC CC 00 00 00    sub         esp,0CCh  
01041809 53                   push        ebx  
0104180A 56                   push        esi  
0104180B 57                   push        edi  
0104180C 51                   push        ecx  
0104180D 8D BD 34 FF FF FF    lea         edi,[ebp-0CCh]  
01041813 B9 33 00 00 00       mov         ecx,33h  
01041818 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
0104181D F3 AB                rep stos    dword ptr es:[edi]  
0104181F 59                   pop         ecx  
01041820 89 4D F8             mov         dword ptr [this],ecx  
01041823 8B 4D F8             mov         ecx,dword ptr [this]  
01041826 E8 0C F8 FF FF       call        Base::Base (01041037h)

Base::Base:
01041037 E9 44 07 00 00       jmp         Base::Base (01041780h) 

    Base()
01041780 55                   push        ebp  
01041781 8B EC                mov         ebp,esp  
01041783 81 EC CC 00 00 00    sub         esp,0CCh  
01041789 53                   push        ebx  
0104178A 56                   push        esi  
0104178B 57                   push        edi  
0104178C 51                   push        ecx  
0104178D 8D BD 34 FF FF FF    lea         edi,[ebp-0CCh]  
01041793 B9 33 00 00 00       mov         ecx,33h  
01041798 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
0104179D F3 AB                rep stos    dword ptr es:[edi]  
0104179F 59                   pop         ecx  
010417A0 89 4D F8             mov         dword ptr [this],ecx  
010417A3 8B 45 F8             mov         eax,dword ptr [this]  
010417A6 C7 00 34 7B 04 01    mov         dword ptr [eax],offset Base::`vftable' (01047B34h) 
//注意此处的不同,没有虚函数的话,[eax]是基类第一个成员的地址,有虚函数存在,此处存放的是该类的虚函数表的地址。

class Base
{
public:
    int x=1;
010417AC 8B 45 F8             mov         eax,dword ptr [this]  
010417AF C7 40 04 01 00 00 00 mov         dword ptr [eax+4],1   //基类的第一个成员地址为[eax+4]
    int b=2;
010417B6 8B 45 F8             mov         eax,dword ptr [this]  
010417B9 C7 40 08 02 00 00 00 mov         dword ptr [eax+8],2  
    {
        x = 3;
010417C0 8B 45 F8             mov         eax,dword ptr [this]  
010417C3 C7 40 04 03 00 00 00 mov         dword ptr [eax+4],3  
        b = 4;
010417CA 8B 45 F8             mov         eax,dword ptr [this]  
010417CD C7 40 08 04 00 00 00 mov         dword ptr [eax+8],4  
    }
010417D4 8B 45 F8             mov         eax,dword ptr [this]  
010417D7 5F                   pop         edi  
010417D8 5E                   pop         esi  
010417D9 5B                   pop         ebx  
010417DA 8B E5                mov         esp,ebp  
    }
010417DC 5D                   pop         ebp  
010417DD C3                   ret  

0104182B 8B 45 F8             mov         eax,dword ptr [this]  
0104182E C7 00 4C 7B 04 01    mov         dword ptr [eax],offset Sub::`vftable' (01047B4Ch)
//将子类的虚表地址修改成该类的虚表地址。

class Sub:Base
{
public:
    int x=10;
01041834 8B 45 F8             mov         eax,dword ptr [this]  
01041837 C7 40 0C 0A 00 00 00 mov         dword ptr [eax+0Ch],0Ah //子类成员变量初始化,在基类成员下面。
    int b=11;
0104183E 8B 45 F8             mov         eax,dword ptr [this]  
01041841 C7 40 10 0B 00 00 00 mov         dword ptr [eax+10h],0Bh  
    int c=12;
01041848 8B 45 F8             mov         eax,dword ptr [this]  
0104184B C7 40 14 0C 00 00 00 mov         dword ptr [eax+14h],0Ch  
    {
        x = 21;
01041852 8B 45 F8             mov         eax,dword ptr [this]  
01041855 C7 40 0C 15 00 00 00 mov         dword ptr [eax+0Ch],15h  
        b = 22;
0104185C 8B 45 F8             mov         eax,dword ptr [this]  
0104185F C7 40 10 16 00 00 00 mov         dword ptr [eax+10h],16h  
        c = 23;
01041866 8B 45 F8             mov         eax,dword ptr [this]  
01041869 C7 40 14 17 00 00 00 mov         dword ptr [eax+14h],17h  
    }
01041870 8B 45 F8             mov         eax,dword ptr [this]  
01041873 5F                   pop         edi  
01041874 5E                   pop         esi  
01041875 5B                   pop         ebx  
01041876 81 C4 CC 00 00 00    add         esp,0CCh  
0104187C 3B EC                cmp         ebp,esp  
0104187E E8 C2 F8 FF FF       call        __RTC_CheckEsp (01041145h)  
01041883 8B E5                mov         esp,ebp  
01041885 5D                   pop         ebp  
01041886 C3                   ret  

    return 0;
01041A60 33 C0                xor         eax,eax 
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页