Re: vfptr
От: aLEXa123  
Дата: 10.09.02 19:51
Оценка:
Не помню где , но удалось найти такой пример — погляди в отладчике на адрес objDer
#include "stdafx.h"  //virtual1.cpp
#include <iostream>
using namespace std;

class Base1 {
  public:
  Base1(){ 
  }
    virtual void f() { cout << "Base1::f" << endl; }
    virtual void g() { cout << "Base1::g" << endl; }
};

class Base2 {
    virtual void f() { cout << "Base2::f" << endl; }
    virtual void g() { cout << "Base2::g" << endl; }
};

class Base3 {
  public:
    virtual void f() { cout << "Base3::f" << endl; }
    virtual void g() { cout << "Base3::g" << endl; }
};

class Derived : public Base1, public Base2, public Base3 {
  public:
  Derived() {
  }
    virtual void fd() { cout << "Derived::fd" << endl; }
    virtual void gd() { cout << "Derived::gd" << endl; }
};

typedef void(*Fun)(void);
#define SOME_VALUE 1
#define _ATL_PACKING 8
//macro returns the offset of the base class vptr in the drive 
#define offsetofclass(base, derived) \
((DWORD)(static_cast<base*>((derived*)_ATL_PACKING))-_ATL_PACKING)

int main() {
    Derived objDer;
    Fun pFun = NULL;
    // calling 1st virtual functions of Base1
    pFun = (Fun)*((int*)*(int*)((int*)&objDer+0)+0);
    pFun();
    pFun = (Fun)*(*(int**)((int*)&objDer+0)+1);
    pFun();
    // calling 1st virtual functions of Derived
    pFun = (Fun)*(*(int**)((int*)&objDer+0)+2);
    pFun();
    pFun = (Fun)*(*(int**)((int*)&objDer+0)+3);
    pFun();
    // calling 1st virtual functions of Base2
    pFun = (Fun)*(*(int**)((int*)&objDer+1)+0);
    pFun();
        pFun = (Fun)*(*(int**)((int*)&objDer+1) +1);    
    pFun();
    // calling 1st virtual functions of Base3
    pFun = (Fun)*(*(int**)((int*)&objDer+2)+0);
    pFun();
    //pFun = (Fun)*(*(int**)((int*)&objDer+2)+1);
    //pFun();
    cout << "increment address of objDer by 8 (assuming it`s a char*)" << endl;
    int **dblptr = (int **) ((char *)&objDer + offsetofclass(Base3, Derived) );
    void(*pFun2)() =  ( void(*)(void) )**dblptr;
    pFun2();
    void *pvoid = (char *)&objDer + offsetofclass(Base3, Derived);
    ((Base3*)(pvoid))->g();
    cout << (DWORD)static_cast<Base1*>((Derived*)SOME_VALUE)-SOME_VALUE << " ";
    cout << (DWORD)static_cast<Base2*>((Derived*)SOME_VALUE)-SOME_VALUE << " ";
    cout << (DWORD)static_cast<Base3*>((Derived*)SOME_VALUE)-SOME_VALUE << endl;
    cout << offsetofclass(Base1, Derived) << " ";  //0
    cout << offsetofclass(Base2, Derived) << " ";  //4
    cout << offsetofclass(Base3, Derived) << endl; //8    
    return 0;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.