Symulowanie metod
Część sekcji Programowanie obiektowe ścieżki C w Coddy. Lekcja 39 z 61.
Wiesz już, jak umieścić wskaźnik na funkcję w strukturze. Prawdziwa moc tkwi w przypisywaniu różnych funkcji do różnych instancji tego samego typu struktury. W ten sposób symulujemy metody o różnym zachowaniu.
Rozważ strukturę reprezentującą działanie z możliwością dostosowania logiki:
typedef void (*ActionFunc)(void);
typedef struct {
const char* name;
ActionFunc execute;
} Action;Podczas tworzenia instancji przypisujesz każdej z nich inną funkcję:
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(); // Wynik: Hello!
farewell.execute(); // Wynik: Goodbye!
return 0;
}Zarówno greet, jak i farewell są tego samego typu (Action), a jednak wywołanie execute dla każdego z nich daje zupełnie inne rezultaty. Struktura nie tylko przechowuje dane. Przechowuje zachowanie, które różni się w zależności od instancji.
Ten wzorzec odzwierciedla sposób działania obiektów w innych językach: każdy obiekt może mieć własną implementację metody, mimo że obiekty te współdzielą ten sam interfejs.
Wyzwanie
ŁatwyZbudujmy system Speaker, który pokazuje, jak różne instancje tego samego typu struktury mogą zachowywać się zupełnie inaczej w zależności od tego, która funkcja zostanie do nich przypisana.
Utworzysz dwa pliki, aby uporządkować kod:
speaker.h: Zdefiniuj typ wskaźnika do funkcji o nazwieSpeakFunc, która nie przyjmuje parametrów i niczego nie zwraca. Następnie zdefiniuj strukturęSpeakerzawierającąname(typuconst char*) oraz wskaźnik do funkcjispeaktypuSpeakFunc.main.c: Dołącz plik nagłówkowy i zaimplementuj trzy różne funkcje wydające dźwięki:bark: wypisujeWoof!meow: wypisujeMeow!chirp: wypisujeChirp!
Speaker, każdą przypisaną do innej funkcji na podstawie danych wejściowych, i wywołaj ich metodyspeak, aby zobaczyć polimorficzne zachowanie w akcji.
Twój program otrzyma dwa wejścia: typ pierwszego głośnika (1 oznacza bark, 2 oznacza meow, 3 oznacza chirp) oraz typ drugiego głośnika (również 1, 2 lub 3).
Utwórz dwie instancje Speaker. Możesz nazwać je dowolnie (na przykład "Dog", "Cat", "Bird" lub po prostu "Speaker1", "Speaker2"). Przypisz każdą z nich do odpowiedniej funkcji na podstawie jej kodu wejściowego, a następnie wywołaj speak dla każdej instancji po kolei.
Przykładowe wyjście, gdy pierwszy typ to 1, a drugi typ to 2:
Woof!
Meow!Przykładowe wyjście, gdy pierwszy typ to 3, a drugi typ to 3:
Chirp!
Chirp!Najważniejsze jest to, że oba głośniki są tego samego typu Speaker, a mimo to generują różne wyjścia, ponieważ każdemu przypisano inną funkcję w polu speak. Pamiętaj, aby użyć strażników dołączania w pliku nagłówkowym.
Spróbuj swoich sił
#include <stdio.h>
#include "speaker.h"
// TODO: Zaimplementuj funkcję bark, która wypisuje "Woof!"
// TODO: Zaimplementuj funkcję meow, która wypisuje "Meow!"
// TODO: Zaimplementuj funkcję chirp, która wypisuje "Chirp!"
int main() {
int type1, type2;
scanf("%d", &type1);
scanf("%d", &type2);
// TODO: Utwórz dwie instancje Speaker
// TODO: Przypisz funkcję speak pierwszej instancji Speaker na podstawie type1
// (1 = bark, 2 = meow, 3 = chirp)
// TODO: Przypisz funkcję speak drugiej instancji Speaker na podstawie type2
// (1 = bark, 2 = meow, 3 = chirp)
// TODO: Wywołaj speak kolejno dla każdej instancji Speaker
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