#include #include #include "base.h" #include "derived.h" #include "field.h" using namespace std; void table(base *pb); int main() { base b(10); derived d(20, 30); cout << "base occupies " << sizeof (base) << " bytes, derived occupies " << sizeof (derived) << " bytes.\n\n"; table(&b); table(&d); base *p = &b; //Two ways to call base::g. When we write line 25, //the computer behaves as if we had written lines 26-27. p->g(); void (*const *vtbl)(base *) = *reinterpret_cast(p); vtbl[3](p); p = &d; //Two ways to call derived::g. When we write line 33, //the computer behaves as if we had written lines 34-35. p->g(); vtbl = *reinterpret_cast(p); vtbl[3](p); return EXIT_SUCCESS; } void table(base *pb) { cout << "Object starting at " << pb << ":\n"; const void *p = pb; const px_t *const vtbl = field(p, "ptr to array of ptrs"); field(p, "base::i"); if (dynamic_cast(pb)) { //if *pb is a derived field(p, "derived::j"); } "The array of five pointers to functions is\n"; p = vtbl; field(p, "vtbl[0]"); field(p, "vtbl[1]"); const pf_t pf = field(p, "vtbl[2]"); const pg_t pg = field(p, "vtbl[3]"); const ph_t ph = field(p, "vtbl[4]"); cout << "Let's call the 3 functions at addresses " << pf << ", " << pg << ", " << ph << ".\n"; pf(pb); //pb->f(); pg(pb); //pb->g(); cout << ph(pb, 10, 20) << "\n\n"; //cout << pb->h(10, 20); }