/* Strukturbeschreibung, noch kein echter Speicherplatz */ struct HaSiObjectClass { int (*do_it) (HaSiObject *obj, int foo); int (*do_another) (int foo); }; /* jetzt wirds haarig: Wir überladen eine Methode von HaSiObjectClass */ /* beschreibt die abgeleitete Klasse */ /* Jedes SomeThing ist auch ein HaSiObject, wir müssen eine HaSiObjectClass * beschreibung mit einbetten */ struct SomeThingClass { HaSiObjectClass parent_klass; int do_something (SomeThing *sth, int bla); /* Zusatzmethode für SomeThing */ }; struct HaSiObject { HaSiObjectClass *klass; }; typedef struct something SomeThing; struct something { HaSiObjectClass parent; int x; int y; }; /* gobj1, .... gobjN, x1, x2, x3, x4, y1, y2, y3, y4 */ struct anotherthing { SomeThing parent; int z; }; /* parent1, parent2, ...., parent(N+8), z1, ..., z4 */ /* Hilfsfunktion: einfacher zu lesen */ int hasi_object_do_it (HaSiObject *hobj, int argument) { return hobj->klass->do_it (hobj, argument); } /* tatsächliche Methodendefinition für hasi_object_do_it() */ /* macht die eigentliche Arbeit */ int hasi_object_do_it_real (HaSiObject *hobj, int argument) { return argument * 27; } /* Methode zum Überschreiben von hasi_object_do_it für SomeThings */ int some_thing_do_it_real (HaSiObject *hobj, int argument) { sthing = (SomeThing *) hobj; return argument * 53; } /* Initialisierung unseres Objektsystems */ /* Speicherbereich für eine Beschreibung der HaSiObject-Klasse */ HaSiObjectClass HaSiObjectBeschreibung; /* Speicherbereich für eine Beschreibung der SomeThing-Klasse */ SomeThingClass SomeThingBeschreibung; /* jetzt befüllen wir die Objektbeschreibung mit Methoden */ int hasi_init () { HaSiObjectBeschreibung.do_it = hasi_object_do_it_real; HaSiObjectBeschreibung.do_another = ....; /* erzwungener Typecast für eine HaSiObjectBeschreibung */ ((struct HaSiObjectBeschreibung) SomeThingBeschreibung).do_it = some_thing_do_it_real; SomeThingBeschreibung.do_something = ....; } /* Konstruktor für ein HaSiObject */ /* mit malloc wird echter Speicher besorgt */ HaSiObject * hasi_object_create () { HaSiObject *neu = malloc (sizeof (struct HaSiObject)); neu->klass = &HaSiObjectBeschreibung; return neu; } /* Konstruktor für SomeThings */ SomeThing * some_thing_create () { /* Speicher bereitstellen */ SomeThing *neu = malloc (sizeof (struct SomeThing)); /* Abkürzungspointer für die Basisklasse */ HaSiObject *hobj_neu = (HaSiObject *) neu; /* Zuweisung einer "Klassenidentität" */ /* klass ist in der Teilstruktur für die Basisklasse */ hobj_neu->klass = &SomeThingBeschreibung; /* Initialisierung der "SomeThing"-spezifischen Member-Variablen */ neu->x = 0; neu->y = 0; } /* Konstruktor int main (int argc, char *argv[]) { HaSiObject *obj1, *obj2; something *st; HaSiObject *hobj; int ergebnis; obj1 = hasi_object_create (); obj2 = hasi_object_create (); ergebnis = hasi_object_do_it (obj1, 12); st = some_thing_create (); hobj = (HaSiObject *) at; st->x = 4; st->y = 3; /* in C++: ergebnis = at.do_it (12) */ ergebnis = hasi_object_do_it (hobj, 12); printf ("das Ergebnis von HaSiObject ist: %d\n", ergebnis); /* jetzt wirds spannend: wir rufen eine überschriebene Funktion auf */ ergebnis = hasi_object_do_it ((HaSiObject *) st, 12); printf ("das Ergebnis von SomeThing ist: %d\n", ergebnis); return 0; }