#include <windows.h>
#include <tchar.h>


#include <iostream>
#include <memory>

class o_1
{
public:
 o_1 () : a_ (0) { std::cout << "o_1()"  << std::endl; }
 virtual ~o_1( ) { std::cout << "~o_1()" << std::endl; }
public:
 virtual void show (void)
 {
  std::cout << "o_1::show("<< a_ <<")" << std::endl;
 }
public:
 int a_;
};

class o_2 : public o_1
{
public:
 o_2 () : o_1(), b_(0) { std::cout << "o_2()"  << std::endl; }
 virtual ~o_2()        { std::cout << "~o_2()" << std::endl; }
public:
 virtual void show (void)
 {
  std::cout << "o_2::show("<< b_ <<")" << std::endl;
 }
public:
 int b_;
};

class o_3 : public o_2
{
public:
 o_3 () : o_2(), c_(0) { std::cout << "o_3()"  << std::endl; }
 virtual ~o_3()        { std::cout << "~o_3()" << std::endl; }
public:
 virtual void show (void)
 {
  std::cout << "o_3::show("<< c_ <<")" << std::endl;
 }
public:
 int c_;
};

unsigned int vftable_of____o_1;
unsigned int vftable_of____o_2;
unsigned int vftable_of____o_3;

unsigned int get__vfp  (void* p)
{
 unsigned int __vfp = 0;

 memcpy (&__vfp, p, 4);

 return __vfp;
}

#pragma warning( push )
#pragma warning( disable: 4313 )
// C4313: 'printf' : '%x' in format string conflicts with argument 1 of type 'xxx'

void init (void)
{
 o_1 *o1=new o_1();
 o_2  o2;
 o_3 *o3=new o_3();

 memcpy (&vftable_of____o_1,  o1, 4);
 memcpy (&vftable_of____o_2, &o2, 4);
 memcpy (&vftable_of____o_3,  o3, 4);

 printf (" \r\n");
 printf ("# o_1::vftable_of____o_1=0x%08x \r\n", vftable_of____o_1);
 printf ("# o_2::vftable_of____o_2=0x%08x \r\n", vftable_of____o_2);
 printf ("# o_3::vftable_of____o_3=0x%08x \r\n", vftable_of____o_3);
 printf (" \r\n");

 delete o1;
 delete o3;
}

void test (void)
{
 o_3 *o = new o_3();
 o_1 *p = o;

 o->a_ = 100;
 o->b_ = 200;
 o->c_ = 300;

 printf (" p    's address=0x%08x \r\n", p);
 printf (" p->a_'s address=0x%08x \r\n", &o->a_);
 printf (" p->b_'s address=0x%08x \r\n", &o->b_);
 printf (" p->c_'s address=0x%08x \r\n", &o->c_);
 p->show ();

 printf (" \r\n");
 printf ("# p's __vfp 0x%08x \r\n", get__vfp(p));
 printf (" \r\n");
 printf ("# p->~o_1() \r\n");
 p->~o_1();
 printf (" \r\n");
 printf ("# p's __vfp 0x%08x \r\n", get__vfp(p));
 printf (" \r\n");
 p->show ();

 printf (" \r\n");
 printf ("# let's get fun! \r\n");
 memcpy (p, &vftable_of____o_3, 4); p->show ();
 memcpy (p, &vftable_of____o_2, 4); p->show ();
 memcpy (p, &vftable_of____o_1, 4); p->show ();


 int   v;
 char *member_variable_ptr;

 member_variable_ptr = (char*)p;

 v = 99;
 member_variable_ptr += 4;
 printf (" \r\n");
 printf ("# one more time! (member_variable_ptr=0x%08x) \r\n", member_variable_ptr);
 memcpy (member_variable_ptr, &v, 4);
 memcpy (p, &vftable_of____o_3, 4); p->show ();
 memcpy (p, &vftable_of____o_2, 4); p->show ();
 memcpy (p, &vftable_of____o_1, 4); p->show ();

 v = 98;
 member_variable_ptr+= 4;
 printf (" \r\n");
 printf ("# one more time! (member_variable_ptr=0x%08x) \r\n", member_variable_ptr);
 memcpy (member_variable_ptr, &v, 4);
 memcpy (p, &vftable_of____o_3, 4); p->show ();
 memcpy (p, &vftable_of____o_2, 4); p->show ();
 memcpy (p, &vftable_of____o_1, 4); p->show ();

 v = 97;
 member_variable_ptr+= 4;
 printf (" \r\n");
 printf ("# one more time! (member_variable_ptr=0x%08x) \r\n", member_variable_ptr);
 memcpy (member_variable_ptr, &v, 4);
 memcpy (p, &vftable_of____o_3, 4); p->show ();
 memcpy (p, &vftable_of____o_2, 4); p->show ();
 memcpy (p, &vftable_of____o_1, 4); p->show ();


 printf (" \r\n");
 printf ("# last time ! \r\n");
 memcpy (p, &vftable_of____o_3, 4);

 delete p;
}

#pragma warning( pop )


int _tmain(int argc, _TCHAR* argv[])
{
 std::cout << "==============================================================" <<std::endl;
 std::cout << "init()" <<std::endl;
 std::cout << "==============================================================" <<std::endl;
 init ();
 std::cout << "==============================================================" <<std::endl;
 std::cout <<std::endl;
 std::cout <<std::endl;
 std::cout <<std::endl;


 std::cout << "==============================================================" <<std::endl;
 std::cout << "test()" <<std::endl;
 std::cout << "==============================================================" <<std::endl;
 test ();
 std::cout << "==============================================================" <<std::endl;
 std::cout <<std::endl;
 std::cout <<std::endl;
 std::cout <<std::endl;

 return 0;
}
-----------------------------------------------------------------------------
==============================================================
init()
==============================================================
o_1()
o_1()
o_2()
o_1()
o_2()
o_3()

# o_1::vftable_of____o_1=0x00418890
# o_2::vftable_of____o_2=0x004188c4
# o_3::vftable_of____o_3=0x004188f4

~o_1()
~o_3()
~o_2()
~o_1()
~o_2()
~o_1()
==============================================================


==============================================================
test()
==============================================================
o_1()
o_2()
o_3()
 p    's address=0x003a6858
 p->a_'s address=0x003a685c
 p->b_'s address=0x003a6860
 p->c_'s address=0x003a6864
o_3::show(300)

# p's __vfp 0x004188f4

# p->~o_1()
~o_3()
~o_2()
~o_1()

# p's __vfp 0x00418890

o_1::show(100)

# let's get fun!
o_3::show(300)
o_2::show(200)
o_1::show(100)

# one more time! (member_variable_ptr=0x003a685c)
o_3::show(300)
o_2::show(200)
o_1::show(99)

# one more time! (member_variable_ptr=0x003a6860)
o_3::show(300)
o_2::show(98)
o_1::show(99)

# one more time! (member_variable_ptr=0x003a6864)
o_3::show(97)
o_2::show(98)
o_1::show(99)

# last time !
~o_3()
~o_2()
~o_1()

==============================================================

Posted by 셈말짓기 :