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

  • 相关阅读:
    [转]ROS学习笔记十一:ROS中数据的记录与重放
    [转]百度Appollo无人车Perception Module 分析
    百度 Apollo无人车平台增加传感器
    [转]Ubuntu16.04安装搜狗输入法
    [转]Ubuntu16 压缩解压文件命令
    Baidu Apollo use: command " rosbag " not fonud
    nvidia-smi command not found Ubuntu 16.04
    启动Turtlesim,输入roscore命令,报错
    Linux系统下安装Nginx
    linux重启后JDk环境变量配置失效最终解决方案
  • 原文地址:https://www.cnblogs.com/liaocheng/p/4748600.html
Copyright © 2011-2022 走看看