#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()
==============================================================