zoukankan      html  css  js  c++  java
  • 虚函数表是个什么鬼?

    在多重继承里的虚函数表可以在vs里面看到,如下

    有一个基类就有一张表,可以通过

        int** pVtab = (int**)&d;
    
        pFun = (Fun)pVtab[0][0];
    来访问每一个虚函数,如下代码:
    // pvtable1.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    
    #include <iostream>
    
    using namespace std;
    
    class Base1 {
    
    public:
    
        Base1(){ cout << "Base1::Base1()" << endl; }
        ~Base1(){ cout << "Base1::~Base1()" << endl; }
    
        virtual void f() { cout << "Base1::f" << endl; }
    
        virtual void g() { cout << "Base1::g" << endl; }
    
        virtual void h() { cout << "Base1::h" << endl; }
    
    
    
    };
    
    class Base2 {
    
    public:
        Base2(){ cout << "Base2::Base2()" << endl; }
        ~Base2(){ cout << "Base2::~Base2()" << endl; }
    
        virtual void f() { cout << "Base2::f" << endl; }
    
        virtual void g() { cout << "Base2::g" << endl; }
    
        virtual void h() { cout << "Base2::h" << endl; }
    
    };
    
    
    class Base3 {
    
    public:
        Base3(){ cout << "Base3::Base3()" << endl; }
        ~Base3(){ cout << "Base3::~Base3()" << endl; }
    
        virtual void f() { cout << "Base3::f" << endl; }
    
        virtual void g() { cout << "Base3::g" << endl; }
    
        virtual void h() { cout << "Base3::h" << endl; }
    
    };
    
    
    class Derive : public Base1, public Base2, public Base3 {
    
    public:
        Derive(){ cout << "Derive::Derive()" << endl; }
         ~Derive(){ cout << "Derive::~Derive()" << endl; }
    
        virtual void f() { cout << "Derive::f" << endl; }
    
        virtual void g1() { cout << "Derive::g1" << endl; }
    
    };
    
    
    typedef void(*Fun)(void);
    
    int doIt() 
    {
    
        Fun pFun = NULL;
    
        Derive d;
    
    
        int** pVtab = (int**)&d;
    
        //Base1's vtable
    
        //pFun = (Fun)*((int*)*(int*)((int*)&d+0)+0);
    
        pFun = (Fun)pVtab[0][0];
    
        pFun();
    
    
        //pFun = (Fun)*((int*)*(int*)((int*)&d+0)+1);
    
        pFun = (Fun)pVtab[0][1];
    
        pFun();
    
    
        //pFun = (Fun)*((int*)*(int*)((int*)&d+0)+2);
    
        pFun = (Fun)pVtab[0][2];
    
        pFun();
    
    
        //Derive's vtable
    
        //pFun = (Fun)*((int*)*(int*)((int*)&d+0)+3);
    
        pFun = (Fun)pVtab[0][3];
    
        pFun();
    
    
        //The tail of the vtable
    
        pFun = (Fun)pVtab[0][4];
    
        cout<<pFun<<endl;
    
    
        //Base2's vtable
    
        //pFun = (Fun)*((int*)*(int*)((int*)&d+1)+0);
    
        pFun = (Fun)pVtab[1][0];
    
        pFun();
    
    
        //pFun = (Fun)*((int*)*(int*)((int*)&d+1)+1);
    
        pFun = (Fun)pVtab[1][1];
    
        pFun();
    
    
        pFun = (Fun)pVtab[1][2];
    
        pFun(); 
    
    
        //The tail of the vtable
    
        pFun = (Fun)pVtab[1][3];
    
        cout<<pFun<<endl;
    
    
        //Base3's vtable
    
        //pFun = (Fun)*((int*)*(int*)((int*)&d+1)+0);
    
        pFun = (Fun)pVtab[2][0];
    
        pFun();
    
    
        //pFun = (Fun)*((int*)*(int*)((int*)&d+1)+1);
    
        pFun = (Fun)pVtab[2][1];
    
        pFun();
    
    
        pFun = (Fun)pVtab[2][2];
    
        pFun(); 
    
    
        //The tail of the vtable
    
        pFun = (Fun)pVtab[2][3];
    
        cout<<pFun<<endl;
    
    
        cout<<sizeof(d)<<endl;
    
        return 0;
    
    }
    
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        doIt();
        return 0;
    }

    运行结果如下:

    最后用sizeof获取对象的大小等于成员变量的大小加上虚函数表指针的大小

  • 相关阅读:
    jQuery--.wrap()方法
    ECharts学习(4)--仪表盘
    ECharts学习(3)--toolbox(工具栏)
    jQuery之核心API
    STM32片上Flash内存映射、页面大小、寄存器映射
    typedef struct bit0 : 1
    ***WARNING L15: MULTIPLE CALL TO SEGMENT
    C/C++ 打印文件名、行号、函数名的方法
    ISP与IAP的区别
    sprintf函数 %6.2f
  • 原文地址:https://www.cnblogs.com/liaocheng/p/4748600.html
Copyright © 2011-2022 走看看