Kontener kształtów
Część sekcji Programowanie obiektowe ścieżki C w Coddy. Lekcja 48 z 61.
Wyzwanie
ŁatwyDoprowadźmy projekt Shape Drawer do wielkiego finału! Utworzysz kontener kształtów, który przechowuje mieszaną kolekcję kół i prostokątów, a następnie przejdziesz przez nie, aby obliczyć łączne pole: demonstrując prawdziwą moc polimorfizmu.
Opierając się na wszystkim, co udało Ci się do tej pory stworzyć, Twój kompletny projekt będzie zawierać:
shape.hishape.c: bazowy interfejs Shape oraz funkcjęprocess_shape.circle.hicircle.c: implementację Circle wraz z konstruktorem i obliczaniem pola.rectangle.hirectangle.c: implementację Rectangle wraz z konstruktorem i obliczaniem pola.main.c: To tutaj dzieje się magia. Utworzysz tablicę wskaźnikówShape*, która może przechowywać kształty dowolnego typu. Wypełnij ją mieszanką kół i prostokątów, a następnie użyj pętli, aby obliczyć i wyświetlić łączne pole wszystkich kształtów.
Twój program otrzyma następujące dane wejściowe:
- Liczbę kształtów do utworzenia
- Dla każdego kształtu: oznaczenie typu (
cdla koła,rdla prostokąta), a następnie jego wymiary
Dla każdego kształtu w kontenerze samodzielnie wywołaj draw i area za pośrednictwem wskaźnika Shape* (shapes[i]->draw(shapes[i]), shapes[i]->area(shapes[i])) i dodaj pole do bieżącej sumy. Nie używaj tutaj process_shape z shape.c: ta funkcja wypisuje dodatkowy wiersz Area: dla każdego kształtu, którego nie ma w oczekiwanym wyniku. Po przetworzeniu wszystkich kształtów wypisz łączne pole z dokładnością do 2 miejsc po przecinku, w formacie Total Area: X.XX.
Przykład z danymi wejściowymi 3, a następnie c 5.0, r 4.0 3.0, c 2.0:
Drawing Circle with radius: 5.00
Drawing Rectangle with width: 4.00 and height: 3.00
Drawing Circle with radius: 2.00
Total Area: 103.11Przykład z danymi wejściowymi 2, a następnie r 6.0 4.0, r 3.0 2.0:
Drawing Rectangle with width: 6.00 and height: 4.00
Drawing Rectangle with width: 3.00 and height: 2.00
Total Area: 30.00Najważniejsze jest to, że Twoja tablica przechowuje wskaźniki Shape*. Nie ma znaczenia, czy każdy element jest w rzeczywistości kołem, czy prostokątem. Gdy przechodzisz przez tablicę i wywołujesz draw oraz area za pośrednictwem każdego wskaźnika, automatycznie wykonywana jest właściwa implementacja, zależnie od sposobu utworzenia danego kształtu. To właśnie polimorfizm w praktyce: jedna pętla, jeden interfejs, wiele zachowań.
Pamiętaj, że w tablicy musisz przechowywać wskaźniki do osadzonych elementów Shape konkretnych kształtów. Do obliczania pola koła użyj wartości 3.14159 dla π.
Ważne: odczytywanie znaku typu kształtu: Po odczytaniu liczby kształtów za pomocą scanf("%d", &n) każde kolejne wywołanie odczytujące znak typu musi pomijać znak nowej linii pozostawiony w buforze wejściowym. Aby to zrobić, użyj spacji na początku ciągu formatującego:
scanf(" %c", &type); // note the space before %cBez spacji na początku scanf odczyta znak nowej linii pozostawiony po poprzednim wejściu zamiast oczekiwanego c lub r, przez co sprawdzenie typu kształtu po cichu się nie powiedzie i nie zostanie wygenerowane żadne wyjście.
Spróbuj swoich sił
#include <stdio.h>
#include <stdlib.h>
#include "shape.h"
#include "circle.h"
#include "rectangle.h"
int main() {
// TODO: Wczytaj liczbę figur
// TODO: Przydziel pamięć na tablice okręgów, prostokątów i wskaźników Shape*
// TODO: Przejdź przez każdą figurę, wczytaj jej typ i wymiary,
// utwórz figurę i zapisz wskaźnik do jej obiektu bazowego w tablicy shapes
// TODO: Przejdź przez tablicę shapes, wywołaj shapes[i]->draw(...) oraz
// bezpośrednio shapes[i]->area(...) i zsumuj pola figur
// (nie wywołuj process_shape: wypisuje dodatkowy wiersz Area)
// TODO: Wypisz sumę pól figur w formacie: Total Area: X.XX
// TODO: Zwolnij przydzieloną pamięć
return 0;
}
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