zoukankan      html  css  js  c++  java
  • 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

    效果截图

  • 相关阅读:
    Jmeter+Ant+Jenkins搭建持续集成的接口测试(推荐 Mark)
    配置sonar、jenkins进行持续审查
    查看端口占用
    CentOS 6.5系统上安装SVN服务器端的方法及目录访问权限配置(转总结)
    Windows批处理 调用程序后 不等待子进程 父进程继续执行命令
    Jmeter笔记:响应断言详解
    Ubuntu 16.04常用快捷键
    如何永久激活(破解) IntelliJ IDEA 2018.2
    Cobbler自动化部署
    Typora使用说明(记录总结)
  • 原文地址:https://www.cnblogs.com/pppyyyzzz/p/14339246.html
Copyright © 2011-2022 走看看