------------------------------------------------------------------------------
MC logo
Dynamic Binding
[^] Modular and Class Abstraction
------------------------------------------------------------------------------
[Ch. 1: Overview and History] [Syntax] [Names and Scope] [Types and Type Systems] [Semantics] [Functions] [Memory Management] [Imperitive Programs and Functional Abstraction] [Modular and Class Abstraction] [Functional Programming] [Logic Programming]
[Translating A Class] [Translating Inheritance] [Dynamic Binding]

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);
}