Wskaźnik „self”
Część sekcji Programowanie obiektowe ścieżki C w Coddy. Lekcja 7 z 61.
W językach obiektowych, takich jak Python czy Java, gdy wywołujesz object.method(), język automatycznie przekazuje sam obiekt do metody. W C musimy zrobić to ręcznie, przekazując wskaźnik do struktury jako pierwszy argument.
Ten wskaźnik jest zwyczajowo nazywany self (zapożyczone z Pythona) lub this (z C++). Daje funkcji dostęp do danych struktury, dzięki czemu może je odczytywać lub modyfikować:
typedef struct {
int health;
} Player;
void player_take_damage(Player *self, int amount) {
self->health -= amount;
}
Wskaźnik self sprawia, że funkcja działa jak metoda. Wie, którego gracza zmodyfikować. Bez niego funkcja nie miałaby dostępu do konkretnej instancji struktury. Wywołując tę funkcję, przekazujesz adres swojej struktury:
Player hero = {100};
player_take_damage(&hero, 25);
// hero.health wynosi teraz 75
Użycie wskaźnika (zamiast bezpośredniego przekazania struktury) jest niezbędne do jej modyfikacji. Jeśli przekażesz strukturę przez wartość, funkcja otrzyma jej kopię, a wszelkie zmiany zostaną utracone po zakończeniu działania funkcji. Wskaźnik zapewnia, że zmiany zostaną zachowane w oryginalnej strukturze.
Wyzwanie
ŁatwyZbudujmy moduł Timer, który śledzi upływające sekundy. Poćwiczysz używanie wzorca wskaźnika "self" do modyfikowania wewnętrznego stanu struktury za pomocą funkcji działających jak metody.
Utworzysz trzy pliki:
timer.h: Zadeklaruj strukturęTimerz jednym elementem członkowskimint seconds. Zadeklaruj też dwie funkcje:timer_tick(przyjmuje wskaźnik do Timer i dodaje określoną liczbę sekund) oraztimer_reset(przyjmuje wskaźnik do Timer i ustawia seconds z powrotem na zero). Użyj strażników dołączania z symbolemTIMER_H.timer.c: Zaimplementuj obie funkcje. Funkcjatimer_tickpowinna przyjmowaćTimer *selfiint amount, a następnie dodawać wartość amount do liczby sekund timera. Funkcjatimer_resetpowinna przyjmowaćTimer *selfi ustawiać liczbę sekund na zero.main.c: Utwórz Timer, wykonaj na nim operacje i wyświetl wyniki.
Otrzymasz dwie liczby całkowite: początkową liczbę sekund timera oraz liczbę sekund do dodania za pomocą tick.
W pliku głównym:
- Zainicjalizuj
Timerpoczątkową wartością w sekundach - Wywołaj
timer_tick, aby dodać określoną liczbę - Wyświetl bieżącą liczbę sekund
- Wywołaj
timer_reset, aby zresetować timer - Ponownie wyświetl liczbę sekund (powinna wynosić 0)
Wyświetl wyniki w tym formacie:
After tick: {seconds}
After reset: {seconds}Na przykład dla wartości początkowej 30 i dodania 15 sekund wynik wyglądałby tak:
After tick: 45
After reset: 0Spróbuj swoich sił
#include <stdio.h>
#include "timer.h"
int main() {
int initial_seconds, amount_to_add;
scanf("%d", &initial_seconds);
scanf("%d", &amount_to_add);
// TODO: Utwórz Timer i zainicjalizuj go wartością initial_seconds
// TODO: Wywołaj timer_tick, aby dodać amount_to_add sekund
// TODO: Wypisz aktualną liczbę sekund w formacie: "After tick: {seconds}"
// TODO: Wywołaj timer_reset, aby zresetować timer
// TODO: Ponownie wypisz liczbę sekund w formacie: "After reset: {seconds}"
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