Methoden simulieren
Teil des Abschnitts Objektorientierte Programmierung der C-Journey von Coddy. Lektion 39 von 61.
Du hast gesehen, wie man einen Funktionszeiger in einer Struktur platziert. Die eigentliche Stärke zeigt sich, wenn du verschiedene Funktionen verschiedenen Instanzen desselben Strukturtyps zuweist. So simulieren wir Methoden mit unterschiedlichem Verhalten.
Betrachte eine Struktur, die eine Aktion mit anpassbarer Logik darstellt:
typedef void (*ActionFunc)(void);
typedef struct {
const char* name;
ActionFunc execute;
} Action;Beim Erstellen von Instanzen verknüpfst du mit jeder davon eine andere Funktion:
void say_hello(void) {
printf("Hello!\n");
}
void say_goodbye(void) {
printf("Goodbye!\n");
}
int main() {
Action greet = { "Greet", say_hello };
Action farewell = { "Farewell", say_goodbye };
greet.execute(); // Ausgabe: Hello!
farewell.execute(); // Ausgabe: Goodbye!
return 0;
}Sowohl greet als auch farewell haben denselben Typ (Action), doch der Aufruf von execute bei jedem von ihnen führt zu völlig unterschiedlichen Ergebnissen. Die Struktur enthält nicht nur Daten. Sie enthält ein Verhalten, das je nach Instanz variiert.
Dieses Muster spiegelt wider, wie Objekte in anderen Sprachen funktionieren: Jedes Objekt kann eine eigene Implementierung einer Methode haben, obwohl sie dieselbe Schnittstelle verwenden.
Aufgabe
EinfachLass uns ein Speaker-System erstellen, das zeigt, wie verschiedene Instanzen desselben Strukturtyps völlig unterschiedliches Verhalten zeigen können, je nachdem, welche Funktion ihnen zugewiesen ist.
Du erstellst zwei Dateien, um deinen Code zu organisieren:
speaker.h: Definiere einen Funktionszeigertyp namensSpeakFunc, der keine Parameter entgegennimmt und nichts zurückgibt. Definiere anschließend eineSpeaker-Struktur mit einemname(einemconst char*) und einem Funktionszeigerspeakvom TypSpeakFunc.main.c: Binde deine Headerdatei ein und implementiere drei verschiedene Sprechfunktionen:bark: gibtWoof!ausmeow: gibtMeow!auschirp: gibtChirp!aus
Speaker-Instanzen, weise jeder abhängig von der Eingabe eine andere Funktion zu und rufe ihrespeak-Methoden auf, um Polymorphie in Aktion zu erleben.
Dein Programm erhält zwei Eingaben: den Typ des ersten Sprechers (1 für bark, 2 für meow, 3 für chirp) und den Typ des zweiten Sprechers (ebenfalls 1, 2 oder 3).
Erstelle zwei Speaker-Instanzen. Du kannst sie beliebig benennen (zum Beispiel „Dog“, „Cat“, „Bird“ oder einfach „Speaker1“, „Speaker2“). Weise jeder Instanz anhand ihres Eingabecodes die passende Funktion zu und rufe dann speak für jede Instanz der Reihe nach auf.
Beispielausgabe, wenn der erste Typ 1 und der zweite Typ 2 ist:
Woof!
Meow!Beispielausgabe, wenn der erste Typ 3 und der zweite Typ 3 ist:
Chirp!
Chirp!Die entscheidende Erkenntnis ist, dass beide Sprecher denselben Typ Speaker haben, aber dennoch unterschiedliche Ausgaben erzeugen, weil jeder eine andere Funktion seinem Element speak zugewiesen hat. Denk daran, Include-Guards in deiner Headerdatei zu verwenden.
Probier es selbst
#include <stdio.h>
#include "speaker.h"
// TODO: Implementiere die Funktion bark, die "Woof!" ausgibt
// TODO: Implementiere die Funktion meow, die "Meow!" ausgibt
// TODO: Implementiere die Funktion chirp, die "Chirp!" ausgibt
int main() {
int type1, type2;
scanf("%d", &type1);
scanf("%d", &type2);
// TODO: Erstelle zwei Instanzen von Speaker
// TODO: Weise der Funktion speak des ersten Speaker anhand von type1 die passende Funktion zu
// (1 = bark, 2 = meow, 3 = chirp)
// TODO: Weise der Funktion speak des zweiten Speaker anhand von type2 die passende Funktion zu
// (1 = bark, 2 = meow, 3 = chirp)
// TODO: Rufe speak für jeden Speaker der Reihe nach auf
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der modularen Programmierung
Header-DateienInclude GuardsQuelldateienStatische FunktionenWiederholung: Modularer Taschenrechner4Kapselung
Konzept der Opaque PointersOpaque Structs definierenGetter und SetterValidierung in SetternRückblick: Die geheime Box2Objekte und Methoden
Structs als ObjekteDer 'Self'-PointerConst-CorrectnessPointer vs. WertHilfsmethodenZusammenfassung: Point Manager5Projekt: Einfaches Bankkonto
Projekt-SetupImplementierung des Kontos8Polymorphismus
Funktionszeiger in StructsMethoden simulierenDas Interface-KonzeptInterfaces implementierenPolymorphe IterationWiederholung: Greeter3Objekt-Lebenszyklus
Konstruktor-MusterDestruktor-MusterStack-InitialisierungTiefe KopieRückblick: String-Wrapper6Vererbung durch Komposition
Struct-EinbettungDie First-Member-RegelZugriff auf Parent-MemberUpcastingRückblick: Formenhierarchie9Projekt: Formen-Zeichner
ProjektübersichtKreis-ImplementierungRechteck-ImplementierungPolymorphe VerwendungShape-ContainerÜbe selbstständig: Online-C-Compiler