zoukankan      html  css  js  c++  java
  • 反汇编->C++虚函数深度分析

    先来查看一简单例子
    1. #include<iostream>
    2. using namespace std;
    3. class Base{
    4. public:
    5. virtual void f() { cout << "base f()被call"<<endl; }
    6. virtual void g() { cout << "父类虚函数G被call" << endl; }
    7. };
    8. class Derive : public Base{
    9. public:
    10. virtual void f() { cout << "子类虚函数f()被call" << endl; }
    11. };
    12. int main()
    13. {
    14. Derive d; //子类对象
    15. Base *pb;//父类指针
    16. pb = &d;//父类指针指向子类对象
    17. int *q =(int*) pb;//取出类对象地址
    18. void(*f)(Derive*) = (void(*)(Derive*))(*(int*)(*q));//取出f()函数地址
    19. void(*g)(Derive*) = (void(*)(Derive*))(*(int*)(*q+4));//取出g()函数地址
    20. f((Derive*)pb);//调用子对象虚函数表的第一个元素
    21. g((Derive*)pb);//调用子对象虚函数表的第二个元素
    22. system("pause");
    23. return 0;
    24. }
    用VS2015调试一番.查看pb保存子对象的地址.

     以上pb保存了子类对象地址,地址为0x003bfb64.来看看.这个子类对象的首4个字节(32位机子)地址保存了啥内容(其实是虚函数表的地址)
     .

    子类对象首4个字节保存了00948b34这个数值.(这个其实是虚函数表的地址).再来看看这个数值保存了啥内容.

     发现这个地址开始 0094142e跟00941424应该就是虚函数的地址了.不信.咋们到反汇编查看该地址内容.

    先查看0x0094142e(函数转为反汇编.其实第一个地址就是跳转).发现没.反汇编已经提示了是Derive::f这个函数
    再看看0x00941424.是Base::g这个函数
    以上可知.一般编译器实现.把虚函数表的地址用放在子对象首4个字节.虚函数表保存的是虚函数的地址.
    1. void(*f)(Derive*) = (void(*)(Derive*))(*(int*)(*q));//取出f()函数地址
    2. void(*g)(Derive*) = (void(*)(Derive*))(*(int*)(*q+4));//取出g()函数地

    比如以上2行.q是子对象的地址.(*q)就是虚函数表的地址 (*q)+4 相当于虚函数的第二个元素的地址. *(int*)(*q)表示第一个虚函数的地址.*(int*)(*q+4));表示第二个虚函数表的地址..最后强制转换为类成员函数.用(void(*)(Derive*).因为一般类成员函数在编译后.首形参是一个this指针.这里用Derive*.因为this指针的类型就是类的类型
    1. f((Derive*)pb);//调用子对象虚函数表的第一个元素
    2. g((Derive*)pb);//调用子对象虚函数表的第二个元素

     最后调用这2个虚函数表中的虚函数.把pb(子对象的地址)当做参数this指针.然后直接调用.即可使得函数被调用了
     
     

     







  • 相关阅读:
    视频播放
    调用原生硬件 Api 实现照相机 拍照和相册选择 以及拍照上传
    获取设备信息 以及 获取地 理位置
    flutter_html 和 WebView 解析html 和 build.gradle源码
    flutter Dio()网络请求
    AlertDialog 、SimpleDialog、 showModalBottomSheet、showToast 自定义 Dialog
    前端小白页面开发注意事项及小工具(htmlcssjs)
    box-shadow 画叮当猫
    什么是冒泡排序?
    console.log
  • 原文地址:https://www.cnblogs.com/zengyiwen/p/5679162.html
Copyright © 2011-2022 走看看