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获取对象的大小等于成员变量的大小加上虚函数表指针的大小

  • 相关阅读:
    【类库】容器对象(List、DataTable、 DataView、Dictionary)
    一些基础知识(一)
    编程模式之15---行为型----命令模式
    .NET学习之路----我对P/Invoke技术的理解(一)
    编程模式之十四----行为型----职责链模式
    web service 学习
    在Windows Server 2008中布置Web站点时遇到的问题及解决办法
    运算符的优先级和结合 性
    打包工具进行打包文件时要注意要点
    登录测试点
  • 原文地址:https://www.cnblogs.com/liaocheng/p/4748600.html
Copyright © 2011-2022 走看看