November 12, 2025, Wednesday, 315

Języki Programowania 6

From MJanik

Revision as of 08:40, 7 November 2025 by Majanik (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Zadanie 6 - Biblioteka c.d.



Zadanie przykładowe.

Contents

Podstawa: Konstruktory

Konstruktor to specjalna metoda w klasie, która uruchamia się automatycznie w momencie tworzenia obiektu. Najważniejsze cechy konstruktora:

  • Nazywa się tak samo jak klasa

W C++ klasa Book ma konstruktor Book().

  • Nie zwraca żadnego typu, nawet void

Dzięki temu kompilator wie, że to konstruktor, a nie zwykła metoda.

  • Służy do inicjalizacji obiektu

Ustawia wartości pól, rezerwuje zasoby, przygotowuje obiekt do użycia. To idealne miejsce, aby nadać polom wartości startowe albo wywołać inne metody inicjalizujące.

  • Może być przeciążany

Możesz mieć kilka konstruktorów z różnymi parametrami — np. jeden pusty, a drugi ustawiający wartości pól.


1. Proszę napisać klasę cmplx, reprezentującą liczbę zespoloną. Klasa powinna mieć dwa składniki: double re oraz double im.

Dla tej klasy należy dodać odpowiednie konstruktory oraz destruktor:

cmplx(); //konstruktor domyślny (obydwa pola domyślnie = 0)

cmplx(float); //pole im powinno być domyślnie = 0 dla tego konstruktora

cmplx(float, float); //konstruktor główny

~cmplx(); // destruktor

Niech konstruktory posiadają wypisywanie na ekran informacji, by móc odróżnić który z nich został użyty. Klasa cmplx powinna zostać zapisana w dwóch oddzielnych plikach: cmplx.cpp oraz cmplx.h.


Ponadto klasa cmplx powinna posiadać metodę print wypisującą część rzeczywistą oraz część urojoną na ekran.


Następnie proszę uruchomić program z funkcją main jak niżej:

int main()
{
cmplx z1;
cout<<endl<<"Oto pierwsza liczba zespolona: "<<endl;
z1.print();

cmplx z2(1.);
cout<<endl<<"Oto druga liczba zespolona: "<<endl;
z2.print();

cmplx z3(1.,1.);
cout<<endl<<"Oto trzecia liczba zespolona: "<<endl;
z3.print();

return 0;
}


Dla zadania 3 takie pojęcia jak:

konstruktor

destruktor

domyślna wartość argumentu

przesyłanie do funkcji argumentow bedacych obiektami: przesyłanie przez wartość i przesyłanie przez referencje

przeładowywanie nazw

new oraz delete, czyli alokacja pamięci w C++

powinny brzmieć dla państwa uszu przyjaźnie i znajomo.


2. Stwórz program z warunkiem wielokrotnego wyboru switch - case, pytający w pętli o podanie liczby od 0-5.

Wpisanie 0 powinno przerwać pętle oraz spowodować opuszczenie programu.

Wpisanie 1 - wypisanie na ekran "!"

Wpisanie 2,3,4,5 - program ponawia pytanie o liczbę.

Wpisanie liczy innej niż dozwolone - program zakomunikuje, iż została wprowadzona błędna wartość.


W kolejnych krokach kontynuujemy zadanie przykładowe z poprzedniego tygodnia: Klasy pracownik, samochod.

1. Krok pierwszy: funkcje zaprzyjaźnione

Funkcje zaprzyjaźnione - funkcje, które mimo, że nie są składnikami klasy maja dostęp do wszystkich (nawet prywatnych i chronionych) składników klasy.

To nie funkcja ma twierdzić, ze przyjaźni sie z klasa, ale sama klasa daje jej dostęp do swoich prywatnych i chronionych składników.

- Funkcja zaprzyjaźniona może być przyjacielem więcej niż jednej klasy!

- Jeśli klasa deklaruje przyjaźń ze wszystkimi funkcjami innej klasy, możemy mieć klasę zaprzyjaźnioną.

- słowo kluczowe: friend

Dodajmy funkcję zaprzyjaznioną z oboma klasami:

friend double suma_wydatkow(Pracownik* pracownicy, int n, Samochod* samochody, int m);

Przyjmuje tablicę pracowników, ilość pracowników, tablicę samochodów, ilość samochodów.

Podlicza cale wydatki firmy: suma pensji pracownikow + wydatki na benzyne (suma spalanie_na_kilometr * km * cena_benzyny) oraz zwraca ja poprzez return.

Cena benzyny może byc zmienną globalna programu:

double cena_benzyny = 5.0;

Jako ze zarówno pensja, jak i cechy samochodu sa prywatne, normalna, niezaprzyjazniona funkcja nie mogła by sie do nich dostać. Jeśli jednak klasy zadeklarują przyjazń z taką funkcją, to bedzie mogla ona bez przeszkód wyciagnąć ich prywatne składniki: w kodzie takiej funkcji będziemy mogli użyć np.: pracownicy[i].pensja

2. Krok drugi: Przesyłanie do funkcji argumentow bedacych obiektami: Przesyłanie przez wartość i przesyłanie przez referencje

Przesyłanie przez wartosc

- funkcja pracuje na kopii

Jeśli klasa jest spora, zużywamy dużo zasobów na utworzenie kopii. Lecz czasem własnie tego chcemy: wyobraźmy sobie, ze firma ma 5 konkretnych Opli i dokupiła nowy, szósty.

Stworz funkcje Samochod SkopiujSamochod(Samochod a) która zwraca obiekt klasy Samochod, identyczny jak jego kopia z jednym wyjątkiem: chcemy, by liczba kilometrów była wyzerowana.


Przesyłanie przez referencje

- funkcja pracuje na oryginale

Wyobraźmy sobie, ze chcemy zmienic ktoryś z parametrów samochodu. Żeby to zrobic odświerzamy cały wpis.

Stworz klase void ZmienSamochod(Samochod &a, rodzaj m, double s, double k) która poprawia obiekt a, przypisując mu nowe wartosci: marki - m, spalanie_na_kilometr - s oraz km - k Obiekt nie musi byc zwracany na koniec, gdyz pracujemy bezpośrednio na obiekcie podanym jako argument.


3. Krok trzeci: Przeładowanie nazw funkcji.

- nadanie jej wielu znaczeń, gdyż istnieje kilka różnych funkcji o tej samej nazwie.

Wyobraźmy sobie, ze zamiast "rodzaju" void ZmienSamochod(Samochod &a, rodzaj m, double s=7, double k=0) jednak chcielibyśmy mieć możliwość podania stringa (np. gdy użytkownik podaje nazwę z klawiatury, a nie dzieje sie to wewnątrz kodu programu): void ZmienSamochod(Samochod &a, string m, double s=7, double k=0).

Jako, że obie funkcje robią dokładnie to samo, chcielibyśmy zachować rownież taką samą nazwę. W C++ można tak zrobic - kompilator sam odkryje, czy podawany przez nas obiekt to integer (enum) czy tez string i bazujac na tej informacji wywoła odpowiednią funkcję.

Dla naszego programu zakładamy, że jedynie te trzy marki samochódow sa dostępne. Chcielibyśmy, żeby funkcja void ZmienSamochod(Samochod &a, string m, double s=7, double k=0) sprawdzała, czy string m jest == "Opel" albo "opel" i na tej podstawie ustawiała markę samochodu na opel (z enum!). Podobnie dla pozostalych marek. a pozostale wartosci przypozadkowala tak samo jak w poprzedniej funkcji.


Informacje dodatkowe: Zaslanianie nazw - Mozna, ale raczej utrudnia zycie, wiec unikamy.