Event-System
Teil des Abschnitts Object Oriented Programming der C-Journey von Coddy — Lektion 61 von 61.
Aufgabe
EinfachLassen Sie uns ein Benachrichtigungssystem bauen — eine ereignisgesteuerte Architektur, bei der mehrere Handler ein Ereignis abonnieren und reagieren können, wenn es ausgelöst wird. Dieses Muster ist das Rückgrat der reaktiven Programmierung und von GUI-Frameworks.
Sie werden Ihren Code über drei Dateien organisieren:
event.h: Definieren Sie den FunktionszeigertypHandler, der eineconst char*Nachricht entgegennimmt. Erstellen Sie einEvent-Struct, das ein Array von bis zu 5 Handlern und eine Anzahl der registrierten Handler enthält. Deklarieren Sie Funktionen zum Initialisieren eines Ereignisses, zum Abonnieren eines Handlers und zum Auslösen des Ereignisses, um alle Abonnenten zu benachrichtigen.event.c: Implementieren Sie Ihr Ereignissystem:init_event— nimmt einen Event-Pointer entgegen und setzt den Handler-Zähler auf 0subscribe— nimmt einen Event-Pointer und einen Handler entgegen, fügt den Handler zum Array hinzu, wenn noch Platz ist (Zähler kleiner als 5), und erhöht den Zählerfire— nimmt einen Event-Pointer und einen Nachrichten-String entgegen und ruft dann jeden registrierten Handler mit dieser Nachricht in der Reihenfolge auf, in der sie abonniert wurden
main.c: Erstellen Sie drei verschiedene Handler-Funktionen, die auf Ereignisse auf einzigartige Weise 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 sie aufgerufen wurde, und gibt dann[COUNT] Xaus, wobei X der aktuelle Zählerstand ist
Ihr Programm erhält:
- Die Anzahl der zu abonnierenden Handler (1, 2 oder 3)
- Die zu sendende Nachricht
Beispielausgabe, wenn die Eingaben 3 und System started sind:
[LOG] System started
[ALERT] System started
[COUNT] 1Beispielausgabe, wenn die Eingaben 2 und Warning detected sind:
[LOG] Warning detected
[ALERT] Warning detectedBeispielausgabe, wenn die Eingaben 1 und Hello sind:
[LOG] HelloDies demonstriert Polymorphismus durch Funktionszeiger — derselbe fire-Aufruf löst völlig unterschiedliche Verhaltensweisen aus, je nachdem, welche Handler abonniert sind. Jeder Handler reagiert auf seine eigene Weise auf dasselbe Ereignis, was die entkoppelte Natur des ereignisgesteuerten Designs zeigt.
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() {
// Liest die Anzahl der zu abonnierenden Handler ein
int num_handlers;
scanf("%d", &num_handlers);
getchar(); // Zeilenumbruch konsumieren
// Liest die Nachricht ein
char message[256];
fgets(message, sizeof(message), stdin);
message[strcspn(message, "\n")] = '\0'; // Zeilenumbruch entfernen
// TODO: Ein Event erstellen und initialisieren
// TODO: Handler basierend auf num_handlers abonnieren
// 1 Handler: logger
// 2 Handler: logger, alert
// 3 Handler: logger, alert, counter
// TODO: Das 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 Object Oriented Programming
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-Implementierung