Inicjalizacja na stosie
Część sekcji Programowanie obiektowe ścieżki C w Coddy. Lekcja 14 z 61.
Nie każdy obiekt musi znajdować się na stercie. Gdy struktura jest mała i ma krótki czas życia, przydzielenie jej na stosie jest prostsze i szybsze: bez malloc, bez free i bez ryzyka wycieków pamięci.
Zamiast zwracać wskaźnik, funkcja fabrykująca może zwrócić strukturę przez wartość. Cała struktura zostaje skopiowana do wywołującego:
typedef struct {
int x;
int y;
} Point;
Point create_point(int x, int y) {
Point p;
p.x = x;
p.y = y;
return p;
}
Wywołujący otrzymuje w pełni zainicjalizowaną kopię:
Point origin = create_point(0, 0);
Point cursor = create_point(100, 50);
printf("Cursor: (%d, %d)\n", cursor.x, cursor.y);
Brak wskaźników, brak konieczności sprzątania. Gdy origin i cursor wyjdą poza zakres, zostaną automatycznie zniszczone.
To podejście sprawdza się najlepiej w przypadku małych struktur bez dynamicznie alokowanych składowych. W przypadku większych obiektów lub tych zawierających wskaźniki do pamięci sterty lepszym wyborem pozostaje wzorzec konstruktora z użyciem malloc.
Wyzwanie
ŁatwyZbudujmy moduł Temperature, który tworzy odczyty temperatury na stosie za pomocą funkcji fabrykującej. W przeciwieństwie do konstruktorów opartych na stercie z poprzednich lekcji, to podejście zwraca strukturę przez wartość: bez malloc, bez free, po prostu prosta i wydajna alokacja na stosie.
Utworzysz trzy pliki:
temperature.h: Zadeklaruj strukturęTemperaturez dwoma polami:double celsiusichar scale(do przechowywania 'C' oznaczającego stopnie Celsjusza). Zadeklaruj też dwie funkcje:create_temperature: przyjmuje wartość typu double i zwraca strukturęTemperatureprzez wartość (a nie wskaźnik!)temperature_to_fahrenheit: przyjmujeconst Temperature *i zwraca równoważną temperaturę w stopniach Fahrenheita jako wartość typu double
TEMPERATURE_H.temperature.c: Zaimplementuj obie funkcje. Funkcja fabrykująca powinna utworzyć lokalną zmiennąTemperature, zainicjalizować jej pola (ustawićscalena'C') i ją zwrócić. Wzór na konwersję to:fahrenheit = celsius * 9.0 / 5.0 + 32.0main.c: Użyj funkcji fabrykującej, aby utworzyć odczyt temperatury i wyświetlić wartości w stopniach Celsjusza i Fahrenheita.
Otrzymasz jedno wejście: temperaturę w stopniach Celsjusza (jako wartość typu double).
W pliku głównym użyj create_temperature, aby utworzyć strukturę Temperature z podaną wartością. Następnie wypisz pierwotną wartość w stopniach Celsjusza i jej odpowiednik w stopniach Fahrenheita.
Wypisz dane wyjściowe w tym formacie:
Celsius: {celsius}
Fahrenheit: {fahrenheit}Użyj %.2f dla obu wartości, aby wyświetlić je z dwoma miejscami po przecinku.
Na przykład dla wejścia 25.0 dane wyjściowe wyglądałyby tak:
Celsius: 25.00
Fahrenheit: 77.00Zwróć uwagę, jak przejrzyste jest to podejście. Otrzymujesz w pełni zainicjalizowaną strukturę bez martwienia się o zarządzanie pamięcią. Gdy zmienna Temperature wyjdzie poza zakres, zostanie automatycznie posprzątana.
Spróbuj swoich sił
#include <stdio.h>
#include "temperature.h"
int main() {
double celsius_input;
scanf("%lf", &celsius_input);
// TODO: Użyj create_temperature, aby utworzyć strukturę Temperature
// TODO: Wypisz wartość w stopniach Celsjusza w formacie %.2f
// TODO: Użyj temperature_to_fahrenheit, aby przeliczyć i wypisać wartość w stopniach Fahrenheita
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