Event-System
Teil des Abschnitts Objektorientierte Programmierung der C-Journey von Coddy. Lektion 61 von 61.
Aufgabe
EinfachErstellen wir ein Benachrichtigungssystem: eine ereignisgesteuerte Architektur, bei der mehrere Handler ein Ereignis abonnieren und reagieren können, wenn es ausgelöst wird. Dieses Muster bildet das Rückgrat der reaktiven Programmierung und von GUI-Frameworks.
Du organisierst deinen Code über drei Dateien:
event.h: Definiere den FunktionszeigertypHandler, der eine Nachricht vom Typconst char*entgegennimmt. Erstelle eineEvent-Struktur, die ein Array mit bis zu 5 Handlern und die Anzahl der registrierten Handler enthält. Deklariere Funktionen zum Initialisieren eines Ereignisses, zum Abonnieren eines Handlers und zum Auslösen des Ereignisses, um alle Abonnenten zu benachrichtigen.event.c: Implementiere dein Ereignissystem:init_event: nimmt einen Event-Zeiger entgegen und setzt die Anzahl der Handler auf 0subscribe: nimmt einen Event-Zeiger und einen Handler entgegen, fügt den Handler dem Array hinzu, wenn noch Platz vorhanden ist (Anzahl kleiner als 5), und erhöht die Anzahlfire: nimmt einen Event-Zeiger und eine Nachrichtenzeichenkette entgegen und ruft anschließend jeden registrierten Handler mit dieser Nachricht in der Reihenfolge auf, in der sie abonniert wurden
main.c: Erstelle drei verschiedene Handler-Funktionen, die auf einzigartige Weise auf Ereignisse reagieren:logger: gibt[LOG]gefolgt von der Nachricht ausalert: gibt[ALERT]gefolgt von der Nachricht auscounter: verwendet eine statische Variable, um zu zählen, wie oft die Funktion aufgerufen wurde, und gibt anschließend[COUNT] Xaus, wobei X die aktuelle Anzahl ist
Dein Programm erhält:
- Die Anzahl der zu abonnierenden Handler (1, 2 oder 3)
- Die zu übertragende Nachricht
Beispielausgabe bei den Eingaben 3 und System started:
[LOG] System started
[ALERT] System started
[COUNT] 1Beispielausgabe bei den Eingaben 2 und Warning detected:
[LOG] Warning detected
[ALERT] Warning detectedBeispielausgabe bei den Eingaben 1 und Hello:
[LOG] HelloDies veranschaulicht Polymorphismus durch Funktionszeiger: Derselbe Aufruf von fire löst je nach den abonnierten Handlern völlig unterschiedliche Verhaltensweisen aus. Jeder Handler reagiert auf seine eigene Weise auf dasselbe Ereignis und verdeutlicht damit die entkoppelte Natur eines ereignisgesteuerten Designs.
Probier es selbst
#include <stdio.h>
#include <string.h>
#include "event.h"
// TODO: Logger-Handler implementieren
// Gibt "[LOG] " gefolgt von der Nachricht aus
void logger(const char* message) {
// TODO: Implementieren
}
// TODO: Alert-Handler implementieren
// Gibt "[ALERT] " gefolgt von der Nachricht aus
void alert(const char* message) {
// TODO: Implementieren
}
// TODO: Counter-Handler implementieren
// Verwendet eine statische Variable, um Aufrufe zu zählen
// Gibt "[COUNT] X" aus, wobei X der aktuelle Zählerstand ist
void counter(const char* message) {
// TODO: Mit statischer Variable implementieren
}
int main() {
// Lies die Anzahl der zu abonnierenden Handler
int num_handlers;
scanf("%d", &num_handlers);
getchar(); // Zeilenumbruch verbrauchen
// Lies die Nachricht
char message[256];
fgets(message, sizeof(message), stdin);
message[strcspn(message, "\n")] = '\0'; // Zeilenumbruch entfernen
// TODO: Event erstellen und initialisieren
// TODO: Handler basierend auf num_handlers abonnieren
// 1 Handler: logger
// 2 Handler: logger, alert
// 3 Handler: logger, alert, counter
// TODO: Event mit der Nachricht auslösen
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 Kontos3Objekt-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