Dostęp do elementów klasy nadrzędnej
Część sekcji Programowanie obiektowe ścieżki C w Coddy. Lekcja 30 z 61.
Skoro rozumiemy już osadzanie struktur i regułę pierwszego elementu, skupmy się na praktycznym aspekcie: jak odczytywać i modyfikować dane osadzonej struktury nadrzędnej z poziomu funkcji.
Gdy funkcja otrzymuje strukturę Child (lub wskaźnik do niej), dostęp do pól rodzica wymaga przejścia przez osadzoną strukturę. Składnia zależy od tego, czy pracujesz z wartością, czy ze wskaźnikiem.
typedef struct {
int id;
int score;
} Parent;
typedef struct {
Parent parent;
char grade;
} Child;Mając wskaźnik do Child, użyj operatora strzałki, aby odwołać się do rodzica, a następnie kropki, aby uzyskać dostęp do jego składowych:
void update_score(Child* c, int new_score) {
c->parent.score = new_score; // Strzałka, potem kropka
}
void print_info(Child* c) {
printf("ID: %d, Score: %d\n", c->parent.id, c->parent.score);
}W przypadku wartości (przekazywanej przez kopię) używaj kropek:
void show_id(Child c) {
printf("ID: %d\n", c.parent.id); // Kropka, a potem kropka
}Ten wzorzec dostępu łańcuchowego, child->parent.member lub child.parent.member, to sposób interakcji z odziedziczonymi danymi w modelu kompozycji języka C. Jest nieco bardziej rozwlekły niż prawdziwe dziedziczenie, ale jasno i wyraźnie określa relację między typami.
Wyzwanie
ŁatwyZbudujmy system oceniania uczniów, który pokazuje, jak uzyskiwać dostęp do danych wewnątrz zagnieżdżonej struktury i modyfikować je. Utworzysz hierarchię, w której Student zawiera zagnieżdżoną strukturę Person, a następnie napiszesz funkcje, które operują na danych elementu nadrzędnego za pośrednictwem elementu potomnego.
Rozmieścisz kod w trzech plikach:
student.h: Zdefiniuj hierarchię struktur z zabezpieczeniami przed wielokrotnym dołączaniem. Utwórz strukturęPersonz polaminame(tablica znaków o długości 50 znaków) iage(liczba całkowita). Następnie zdefiniuj strukturęStudent, która zawieraPersonjako swój pierwszy element i dodaje polegrade(liczbę całkowitą reprezentującą ocenę). Zadeklaruj dwie funkcje:set_person_age, która przyjmujeStudent*i nową wartość wieku, orazprint_student, która przyjmujeStudent*i wyświetla wszystkie informacje.student.c: Zaimplementuj obie funkcje. Funkcjaset_person_agepowinna modyfikować wiek wewnątrz zagnieżdżonej strukturyPerson. To tutaj przećwiczysz składnię strzałka-kropka (s->person.age). Funkcjaprint_studentpowinna uzyskiwać dostęp do wszystkich pól zarówno zagnieżdżonej osoby, jak i samego ucznia oraz je wyświetlać.main.c: Utwórz zmienną typuStudenti zainicjalizuj wszystkie jej pola. Następnie użyjset_person_age, aby zaktualizować wiek zagnieżdżonej osoby, i wywołajprint_student, aby wyświetlić wynik.
Otrzymasz cztery dane wejściowe: imię i nazwisko ucznia (ciąg znaków), jego wiek początkowy (liczbę całkowitą), jego ocenę (liczbę całkowitą) oraz nowy wiek (liczbę całkowitą, na którą wiek zostanie zaktualizowany za pomocą Twojej funkcji).
W pliku głównym utwórz ucznia z początkowymi wartościami, a następnie wywołaj set_person_age, aby zmienić wiek na nową wartość, i na koniec wywołaj print_student, aby wyświetlić zaktualizowane informacje.
Wynik powinien wyglądać tak:
Name: Emma
Age: 21
Grade: 85Gdzie Emma to imię i nazwisko, 21 to zaktualizowany wiek (a nie wiek początkowy), a 85 to ocena. Kluczowa umiejętność, którą tu zdobędziesz, to poruszanie się po zagnieżdżonej strukturze, aby odczytywać i zapisywać pola elementu nadrzędnego.
Spróbuj swoich sił
#include <stdio.h>
#include <string.h>
#include "student.h"
int main() {
char name[50];
int initial_age, grade, new_age;
// Wczytaj dane wejściowe
fgets(name, 50, stdin);
name[strcspn(name, "\n")] = '\0'; // Usuń znak nowej linii
scanf("%d", &initial_age);
scanf("%d", &grade);
scanf("%d", &new_age);
// TODO: Utwórz zmienną typu Student
// TODO: Zainicjalizuj wszystkie pola studenta
// - Skopiuj name do pola name osadzonej osoby za pomocą strcpy
// - Ustaw wiek osadzonej osoby na initial_age
// - Ustaw ocenę studenta
// TODO: Wywołaj set_person_age, aby zmienić wiek na new_age
// TODO: Wywołaj print_student, aby wyświetlić wynik
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