zoukankan      html  css  js  c++  java
  • 虚表思考再探虚表布局

     


    思考类的布局,以前一直以为 一个类可能有多个虚表。
    今天下午特别的写程序测试下。

     

    程序参考了:陈皓博客的

    结论是:无论一个类怎么继承来的,他的虚表只有一个!//

    感觉:注意:虚表的理解,至少2个层次,动静结合
    静,要知道 类的布局
    动,要知道函数 动态绑定

     

    #include "stdafx.h"

    #include <iostream>

    using namespace std;

    class Base{

    //private:

    public:

      //virtual  ~Base()

      //{cout<<"i am in dtor"<<endl;//只有显示申明后才object中显示

      //}

    public:

      virtual void f() { cout << "Base::f" << endl; }

      virtual void g() { cout << "Base::g" << endl; }

      void h() { cout << "unvirtual Base::h" << endl; }

    };

    class derived:public Base{

    public:

      //virtual void f() { cout << "derived::f" << endl; } //使用父亲的

      virtual void g() { cout << "derived::g" << endl; }

      void h() { cout << "unvirtual derived::h" << endl; }

      virtual void i() { cout << "his own derived::i" << endl; }

    };

    void test_Main(){

      typedef void(*Fun)(void);

      Base b;

      Fun pFun = NULL;

      cout << "vtbl address" << (int*)(&b) << endl;

      cout << "vtbl 1st function" << (int*)*(int*)(&b) << endl;

      cout<<"打印转换过程"<<&b<<" "<<(int*)(&b)<<" "<<*(int*)(&b)<<" "<<(int*)*(int*)(&b)<<endl;

      cout<<"在此打印地址+ "<<&b+1<<" "<<(int*)(&b)+1<<" "<<*(int*)(&b)+1<<" "<<(int*)*(int*)(&b) +1<<endl;

      // Invoke the first virtual function

      pFun = (Fun)*((int*)*(int*)(&b));

      ( (Fun)*((int*)*(int*)(&b)) )();

         //奇怪的bug:显示的dtor,就要这里报错//这里就注释了base dtor

         //( (Fun)*((int*)*(&b)) )();//无法从Base转换为int *

         //( (Fun)*(*(int*)(&b)) )();//error C2100: 非法的间接寻址

         //( *((int*)*(int*)(&b)) )(); //error C2064: 项不会计算为接受0 个参数的函数

                       //不强制转换报错!不知道返回类型,不知道参数。所以转换

     

     

      pFun();

      (Fun)*((int*)*(int*)(&b)+0);  // Base::f()

      pFun();

      pFun=(Fun)*((int*)*(int*)(&b)+1);  // Base::g()

      pFun();

      //pFun=(Fun)*((int*)*(int*)(&b)+2);  // Base::h() //不存在vtbl..用户可以自己调用析构?

      //pFun();

     

     

      derived d;

          (  (Fun)* (int *)*(int *)(&d) ) ();//调用保留的函数

             // (Fun)* (int *)*(int *)(&d)  (); //结合性会计算为接受0 个参数的函数

        ( (Fun)* ( (int *)*(int *)(&d) +1) )();//调用重写

        ( (Fun)* ( (int *)*(int *)(&d) +2) )(); //调用新的虚函数

    }

     

    //调试方法:就是调用

    test_Main()

     

    后面试我的测试截图:

     

     

    image

     补上虚表转换图示:

  • 相关阅读:
    Ubuntu14.04LTS系统QQ的安装:pidgin-lwqq
    Ubuntu14.04LTS系统输入法的安装
    Linux系统安装及初始化(ubuntu14.04)
    创建RAID并永久挂载RAID
    磁盘管理和磁盘配额
    用户账号组账号概述
    安装及管理程序
    目录和文件管理
    Vi编辑器的工作模式
    Linux命令及使用方法
  • 原文地址:https://www.cnblogs.com/titer1/p/2620452.html
Copyright © 2011-2022 走看看