飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 1763|回复: 2

[C/C++] 虚表之完全模拟

[复制链接]

该用户从未签到

发表于 2010-1-28 15:51:55 | 显示全部楼层 |阅读模式
#include "stdafx.h"
#include <iOStream.h>
#include <string.h>

#define  TABLE_MAX 10

class Base;
class Dirive;

typedef void (Base::*FUNC_BASE)();
typedef void (Dirive::*FUNC_DIRIVE)();
typedef void (*FUNC_STATIC)();
typedef Base*(*FUNC_BASE_STATIC)();

FUNC_BASE vtable_base[TABLE_MAX];
FUNC_DIRIVE vtable_dirive[TABLE_MAX];

//////////////////////////////////////////////////////////////////////////
//  基类
//////////////////////////////////////////////////////////////////////////

class Base
{
public:
        FUNC_BASE * m_pVtable;
public:
        Base()
        {
                m_pVtable = vtable_base;
        }
        ~Base(){}
        void ShowMe()
        {
                cout<< "Hello,I am Base!" <<endl;
        }
        static void ShowMeTwo()
        {
                cout<< "Hello,I am Base Two!" <<endl;
        }
        static void InitTable();
};

void Base::InitTable()
{
        *(vtable_base + 0) = Base::ShowMe;
        FUNC_STATIC p = Base::ShowMeTwo ;
        memcpy(vtable_base + 1,&p,sizeof(FUNC_STATIC));
}

//////////////////////////////////////////////////////////////////////////
//  派生类
//////////////////////////////////////////////////////////////////////////

class Dirive : public Base
{
public:
        Dirive()
        {
                m_pVtable = (FUNC_BASE *)vtable_dirive;
        }
        ~Dirive(){}
        void ShowMe()
        {
                cout<< "Hello,I am Dirive!" <<endl;
        }
        static void ShowMeTwo()
        {
                cout<< "Hello,I am Dirive Two!" <<endl;
        }
        static void InitTable();
};

void Dirive::InitTable()
{
        *(vtable_dirive + 0) = Dirive::ShowMe;
        FUNC_STATIC p = Dirive::ShowMeTwo ;
        memcpy(vtable_dirive + 1,&p,sizeof(FUNC_STATIC));
}

//////////////////////////////////////////////////////////////////////////
//  虚表构造类
//////////////////////////////////////////////////////////////////////////

class InitVTable
{
public:
        InitVTable();
        virtual ~InitVTable(){}
};

InitVTable::InitVTable()
{
        Base::InitTable();
        Dirive::InitTable();
}

//////////////////////////////////////////////////////////////////////////
//  main函数部分
//////////////////////////////////////////////////////////////////////////

InitVTable vt;

int main(int argc, char* argv[])
{
        Base theObjB;
        (theObjB.*theObjB.m_pVtable[0])();
       
        (theObjB.*theObjB.m_pVtable[1])();  // 这种带了一个this指针的参数
       
        FUNC_STATIC p ;
        memcpy(&p,&(theObjB.m_pVtable[1]),sizeof(FUNC_STATIC));
        p();                                                       
        // 这种调用就当全局函数来调用了

        Dirive theObjD;
        (theObjD.*theObjD.m_pVtable[0])();
       
        return 0;
}


不用 memcpy 如何实现赋值和调用呢 ???
PYG19周年生日快乐!

该用户从未签到

 楼主| 发表于 2010-1-28 16:37:24 | 显示全部楼层
函数指针 类间是可以实现转化的
但是 类的函数和全局函数是无法进行转化的 如果非要想转化 那就强制赋值吧

/:010 把静态的函数放到虚表里去调用 不用memcpy 我弄不了了
PYG19周年生日快乐!

该用户从未签到

发表于 2010-1-28 20:12:32 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
PYG19周年生日快乐!
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表