Menu
Coddy logo textTech

Methoden simulieren

Teil des Abschnitts Object Oriented Programming der C-Journey von Coddy — Lektion 39 von 61.

Sie haben gesehen, wie man einen Funktionszeiger in einem struct platziert. Die wahre Stärke zeigt sich, wenn Sie verschiedene Funktionen verschiedenen Instanzen desselben struct-Typs zuweisen — so simulieren wir Methoden mit unterschiedlichem Verhalten.

Betrachten Sie ein Struct, das eine Aktion mit anpassbarer Logik darstellt:

typedef void (*ActionFunc)(void);

typedef struct {
    const char* name;
    ActionFunc execute;
} Action;

Beim Erstellen von Instanzen verknüpfen Sie verschiedene Funktionen mit jeder einzelnen:

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 sind vom gleichen Typ (Action), dennoch führt der Aufruf von execute bei jedem zu völlig unterschiedlichen Ergebnissen. Das Struct enthält nicht nur Daten – es enthält Verhalten, das je nach Instanz variiert.

Dieses Muster spiegelt wider, wie Objekte in anderen Sprachen funktionieren: Jedes Objekt kann seine eigene Implementierung einer Methode haben, obwohl sie dieselbe Schnittstelle teilen.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Speaker-System bauen, das demonstriert, wie verschiedene Instanzen desselben Struct-Typs völlig unterschiedliche Verhaltensweisen zeigen können, je nachdem, welche Funktion in sie eingebunden ist.

Sie werden zwei Dateien erstellen, um Ihren Code zu organisieren:

  • speaker.h: Definieren Sie einen Funktionszeigertyp namens SpeakFunc, der keine Parameter entgegennimmt und nichts zurückgibt. Definieren Sie dann ein Speaker-Struct, das einen name (ein const char*) und einen speak-Funktionszeiger vom Typ SpeakFunc enthält.
  • main.c: Binden Sie Ihren Header ein und implementieren Sie drei verschiedene Sprechfunktionen:
    • bark — gibt Woof! aus
    • meow — gibt Meow! aus
    • chirp — gibt Chirp! aus
    Erstellen Sie dann zwei Speaker-Instanzen, die jeweils basierend auf der Eingabe mit einer anderen Funktion verknüpft sind, und rufen Sie deren speak-Methoden auf, um polymorphes Verhalten in Aktion zu sehen.

Ihr Programm erhält zwei Eingaben: den ersten Lautsprechertyp (1 für bark, 2 für meow, 3 für chirp) und den zweiten Lautsprechertyp (ebenfalls 1, 2 oder 3).

Erstellen Sie zwei Speaker-Instanzen — Sie können sie beliebig benennen (wie z. B. "Dog", "Cat", "Bird" oder einfach "Speaker1", "Speaker2"). Verknüpfen Sie jede Instanz basierend auf ihrem Eingabecode mit der entsprechenden Funktion und rufen Sie dann nacheinander speak für jede Instanz auf.

Beispielhafte Ausgabe, wenn der erste Typ 1 und der zweite Typ 2 ist:

Woof!
Meow!

Beispielhafte Ausgabe, wenn der erste Typ 3 und der zweite Typ 3 ist:

Chirp!
Chirp!

Die entscheidende Erkenntnis hierbei ist, dass beide Lautsprecher vom selben Typ Speaker sind, aber unterschiedliche Ausgaben erzeugen, da jedem eine andere Funktion seinem speak-Member zugewiesen wurde. Denken Sie daran, Include-Guards in Ihrer Header-Datei zu verwenden.

Spickzettel

Verschiedene Instanzen desselben Struct-Typs können unterschiedliche Funktionszeiger enthalten, was polymorphes Verhalten ermöglicht.

Definieren Sie einen Funktionszeigertyp und ein Struct, das diesen verwendet:

typedef void (*ActionFunc)(void);

typedef struct {
    const char* name;
    ActionFunc execute;
} Action;

Erstellen Sie Instanzen mit zugewiesenen unterschiedlichen Funktionen:

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();    // Output: Hello!
    farewell.execute(); // Output: Goodbye!
    return 0;
}

Beide Instanzen teilen denselben Typ, zeigen jedoch unterschiedliches Verhalten, wenn ihre Funktionszeiger aufgerufen werden.

Probier es selbst

#include <stdio.h>
#include "speaker.h"

// TODO: Implementiere die bark-Funktion, die "Woof!" ausgibt

// TODO: Implementiere die meow-Funktion, die "Meow!" ausgibt

// TODO: Implementiere die chirp-Funktion, die "Chirp!" ausgibt

int main() {
    int type1, type2;
    scanf("%d", &type1);
    scanf("%d", &type2);
    
    // TODO: Erstelle zwei Speaker-Instanzen
    
    // TODO: Verknüpfe die speak-Funktion des ersten Speakers basierend auf type1
    // (1 = bark, 2 = meow, 3 = chirp)
    
    // TODO: Verknüpfe die speak-Funktion des zweiten Speakers basierend auf type2
    // (1 = bark, 2 = meow, 3 = chirp)
    
    // TODO: Rufe speak für jeden Speaker der Reihe nach auf
    
    return 0;
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Object Oriented Programming