虚函数表是个什么鬼?

在多重继承里的虚函数表可以在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获取对象的大小等于成员变量的大小加上虚函数表指针的大小

posted @   廖先生  阅读(480)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示