System zdarzeń
Część sekcji Programowanie obiektowe ścieżki C w Coddy. Lekcja 61 z 61.
Wyzwanie
ŁatwyZbudujmy system powiadomień: architekturę sterowaną zdarzeniami, w której wiele procedur obsługi może subskrybować zdarzenie i reagować, gdy zostanie wywołane. Ten wzorzec stanowi podstawę programowania reaktywnego i frameworków GUI.
Rozmieścisz swój kod w trzech plikach:
event.h: Zdefiniuj typ wskaźnika na funkcjęHandler, który przyjmuje komunikat typuconst char*. Utwórz strukturęEvent, która przechowuje tablicę zawierającą maksymalnie 5 procedur obsługi oraz liczbę zarejestrowanych procedur obsługi. Zadeklaruj funkcje inicjalizujące zdarzenie, subskrybujące procedurę obsługi i wywołujące zdarzenie, aby powiadomić wszystkich subskrybentów.event.c: Zaimplementuj system zdarzeń:init_event: przyjmuje wskaźnik do Event i ustawia liczbę procedur obsługi na 0subscribe: przyjmuje wskaźnik do Event i Handler, dodaje procedurę obsługi do tablicy, jeśli jest miejsce (liczba jest mniejsza niż 5), i zwiększa tę liczbęfire: przyjmuje wskaźnik do Event i ciąg znaków z komunikatem, a następnie wywołuje każdą zarejestrowaną procedurę obsługi z tym komunikatem w kolejności, w jakiej zostały subskrybowane
main.c: Utwórz trzy różne funkcje obsługi, które reagują na zdarzenia w unikalny sposób:logger: wyświetla[LOG], a następnie komunikatalert: wyświetla[ALERT], a następnie komunikatcounter: używa zmiennej statycznej do zliczania, ile razy została wywołana, a następnie wyświetla[COUNT] X, gdzie X oznacza bieżącą liczbę
Twój program otrzyma:
- Liczbę procedur obsługi do zasubskrybowania (1, 2 lub 3)
- Komunikat do rozesłania
Przykładowy wynik dla danych wejściowych 3 i System started:
[LOG] System started
[ALERT] System started
[COUNT] 1Przykładowy wynik dla danych wejściowych 2 i Warning detected:
[LOG] Warning detected
[ALERT] Warning detectedPrzykładowy wynik dla danych wejściowych 1 i Hello:
[LOG] HelloTo pokazuje polimorfizm za pomocą wskaźników na funkcje: to samo wywołanie fire uruchamia zupełnie różne działania w zależności od tego, które procedury obsługi zostały subskrybowane. Każda procedura obsługi reaguje na to samo zdarzenie na swój własny sposób, ukazując luźne powiązanie charakterystyczne dla projektowania sterowanego zdarzeniami.
Spróbuj swoich sił
#include <stdio.h>
#include <string.h>
#include "event.h"
// TODO: Zaimplementuj procedurę obsługi logger
// Wypisuje "[LOG] ", a następnie wiadomość
void logger(const char* message) {
// TODO: Zaimplementuj
}
// TODO: Zaimplementuj procedurę obsługi alert
// Wypisuje "[ALERT] ", a następnie wiadomość
void alert(const char* message) {
// TODO: Zaimplementuj
}
// TODO: Zaimplementuj procedurę obsługi counter
// Używa zmiennej statycznej do zliczania wywołań
// Wypisuje "[COUNT] X", gdzie X to aktualna liczba wywołań
void counter(const char* message) {
// TODO: Zaimplementuj przy użyciu zmiennej statycznej
}
int main() {
// Wczytaj liczbę procedur obsługi do subskrybowania
int num_handlers;
scanf("%d", &num_handlers);
getchar(); // pobierz znak nowej linii
// Wczytaj wiadomość
char message[256];
fgets(message, sizeof(message), stdin);
message[strcspn(message, "\n")] = '\0'; // usuń znak nowej linii
// TODO: Utwórz i zainicjalizuj Event
// TODO: Zarejestruj procedury obsługi na podstawie num_handlers
// 1 procedura obsługi: logger
// 2 procedury obsługi: logger, alert
// 3 procedury obsługi: logger, alert, counter
// TODO: Wywołaj zdarzenie z komunikatem
return 0;
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania modularnego
Pliki nagłówkoweZabezpieczenia przed wielokrotnym dołączeniemPliki źródłoweFunkcje statycznePodsumowanie: kalkulator modularny4Enkapsulacja
Koncepcja niejawnych wskaźnikówDefiniowanie niejawnych strukturGettery i setteryWalidacja w setterachPowtórka: tajemnicze pudełko2Obiekty i metody
Struktury jako obiektyWskaźnik „self”Poprawność constWskaźnik czy wartośćMetody pomocniczePodsumowanie: menedżer punktów5Projekt: Proste konto bankowe
Konfiguracja projektuImplementacja konta8Polimorfizm
Wskaźniki do funkcji w strukturachSymulowanie metodKoncepcja interfejsuImplementowanie interfejsówIteracja polimorficznaPodsumowanie: Greeter11Wzorce projektowe w C
Wzorzec SingletonWzorzec fabrykiWzorzec iteratoraPodsumowanie: fabryka loggera3Cykl życia obiektu
Wzorzec konstruktoraWzorzec destruktoraInicjalizacja na stosieKopia głębokaPodsumowanie: klasa opakowująca ciąg znaków6Dziedziczenie przez kompozycję
Osadzanie strukturZasada pierwszego elementuDostęp do elementów klasy nadrzędnejKonwersja w górę hierarchiiPodsumowanie: hierarchia kształtów9Projekt: Rysownik kształtów
Przegląd projektuImplementacja kołaImplementacja prostokątaZastosowanie polimorfizmuKontener kształtówPoćwicz samodzielnie: Kompilator C online