Translating derived classes relies on the first part of the dynamic structures being the same. That way a pointer to the derived class object also points to the base class part of that object.
Note: The translation is not quite real C code, but making it compile would render the code slightly less clear than it already isn't.
class Base {
private: int x,y,z; public: Base(int a) { x = a; y = z = 0; } void joe(int m) { y = m; } virtual int bill(int m) { y += m; return 2*y; } virtual void albert() { x -= z; } }; class Derived: public Base { private: int q; public: Derived(int m, int n): Base(m) { q = n; } virtual int bill(int m) { q += n; return z; } virtual void sandy(int m, int n) { albert(); q -= n*m; } }; void g(Base *bp) { int n = bp->bill(20); pb->joe(44); pb->albert(); } main() { Base b(10); Derived d(9,11); g(&d); } | struct {
void *vtable[2] = { &Base_bill, &Base_albert }; } Base_static_part; struct Base_dynamic_part { void **vptr; int x,y,z; }; void Base_Base(struct Base_dynamic_part *this, int a) { this->vptr = Base_static_part.vtable; this->x = a; this->y = this->z = 0; } void Base_joe(struct Base_dynamic_part *this, int m) { this->y = m; } void Base_bill(struct Base_dynamic_part *this, int m) { this->y = += m; return 2*this->y; } void Base_albert(struct Base_dynamic_part *this) { this->x -= this->z; } struct { void *vtable[3] = { &Derived_bill, &Base_albert, &Derived_sandy }; } Base_static_part; struct Derived_dynamic_part { void **vptr; // Exact copy of Base_dynamic_part data area. int x,y,z; // Add new stuff. int q; }; void Derived_Derived(Derived_dynamic_part *this, int m, int n) { Base_Base((Base_dynamic_part *)this, m); this->vptr = Derived_static_part.vtable; this->q = n; } int Derived_bill(Derived_dynamic_part *this, int n) { this->q += n; return this->z; } void Derived_sandy(Derived_dynamic_part *this, int m, int n) { this->vptr[1](this); this->q -= n*m; } void g(Base_dynamic_part *bp) { int n = bp->vptr[0](bp,20); Base_joe(pb, 44); bp->vptr[1](bp); } main() { Base_dynamic_part b; Base_Base(&b, 10); Derived_dynamic_part d; Derived_Derived(&d, 9, 11); g(&d); } |