C++关于继承里虚函数的一些动态绑定与静态绑定

类设计

A类

class A
{

private:
    std::string s;
public:
    A()
    {
        s = "abcdefg";
    }

    virtual void vfunc1()
    {
        cout << "A:vfunc1" << endl;
    }
};

B类

class B :public A
{
    virtual void vfunc1()
    {
        cout << "B:vfunc1" << endl;
    }
};

测试代码

void testBinding()
{
    B b;
    A a = (A)b;
    a.vfunc1();

    A* pa = new B;
    pa->vfunc1();

    pa = &b;
    pa->vfunc1();
}

再来看看反汇编后的形式

    B b;
00EF9A6A  lea         ecx,[b]  
00EF9A6D  call        B::B (0EF1366h)  
00EF9A72  mov         dword ptr [ebp-4],0  
    A a = (A)b;
00EF9A79  lea         eax,[b]  
00EF9A7C  push        eax  
00EF9A7D  lea         ecx,[a]  
00EF9A80  call        A::A (0EF134Dh)  
00EF9A85  mov         byte ptr [ebp-4],1  
    a.vfunc1();
00EF9A89  lea         ecx,[a]  
00EF9A8C  call        A::vfunc1 (0EF1168h)  

    A* pa = new B;
00EF9A91  push        20h  
00EF9A93  call        operator new (0EF11A4h)  
00EF9A98  add         esp,4  
00EF9A9B  mov         dword ptr [ebp-140h],eax  
00EF9AA1  mov         byte ptr [ebp-4],2  
00EF9AA5  cmp         dword ptr [ebp-140h],0  
00EF9AAC  je          testBinding+0A1h (0EF9AC1h)  
00EF9AAE  mov         ecx,dword ptr [ebp-140h]  
00EF9AB4  call        B::B (0EF1366h)  
00EF9AB9  mov         dword ptr [ebp-148h],eax  
00EF9ABF  jmp         testBinding+0ABh (0EF9ACBh)  
00EF9AC1  mov         dword ptr [ebp-148h],0  
00EF9ACB  mov         eax,dword ptr [ebp-148h]  
00EF9AD1  mov         dword ptr [ebp-134h],eax  
00EF9AD7  mov         byte ptr [ebp-4],1  
00EF9ADB  mov         ecx,dword ptr [ebp-134h]  
00EF9AE1  mov         dword ptr [pa],ecx  
    pa->vfunc1();
00EF9AE4  mov         eax,dword ptr [pa]  
00EF9AE7  mov         edx,dword ptr [eax]  
00EF9AE9  mov         esi,esp  
00EF9AEB  mov         ecx,dword ptr [pa]  
00EF9AEE  mov         eax,dword ptr [edx]  
00EF9AF0  call        eax  
00EF9AF2  cmp         esi,esp  
00EF9AF4  call        __RTC_CheckEsp (0EF1406h)  

    pa = &b;
00EF9AF9  lea         eax,[b]  
00EF9AFC  mov         dword ptr [pa],eax  
    pa->vfunc1();
00EF9AFF  mov         eax,dword ptr [pa]  
00EF9B02  mov         edx,dword ptr [eax]  
00EF9B04  mov         esi,esp  
00EF9B06  mov         ecx,dword ptr [pa]  
00EF9B09  mov         eax,dword ptr [edx]  
00EF9B0B  call        eax  
00EF9B0D  cmp         esi,esp  
00EF9B0F  call        __RTC_CheckEsp (0EF1406h)  
}
  1. 我们可以看到汇编中的静态绑定是直接调用了A的::vfunc1
  2. 而动态绑定则是将对象自身传给了pa,并向上转型,调用的就是自身的vfunc1

效果截图

原文地址:https://www.cnblogs.com/pppyyyzzz/p/14339246.html