Języki Programowania 6From MJanik
Zadanie przykładowe. Kontynuujemy zadanie przykładowe z poprzedniego tygodnia: Klasy pracownik, samochod. 1. Krok pierwszy: funkcje zaprzyjaźnioneFunkcje 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 referencjePrzesył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.
- 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.
|