From MJanik
(Difference between revisions)
|
|
| Line 1: |
Line 1: |
| - | Grupa poniedziałek 14:00 - 16:00
| |
| | | | |
| - | [http://www.if.pw.edu.pl/~majanik/data/JP/2012/Zadanie6.Krzyzowka.1.pdf Laboratorium 6 ]: klasa Krzyżówka - tablice dwuwymiarowe, operatory.
| |
| | | | |
| | | | |
| - | Grupa wtorek 8:00 - 10:00
| + | Zadanie przykładowe. |
| | | | |
| - | [http://www.if.pw.edu.pl/~majanik/data/JP/2012/Zadanie6.Macierz.2.pdf Laboratorium 6 ]: klasa Macierz - tablice dwuwymiarowe, operatory. | + | Kontynuujemy zadanie przykładowe z poprzedniego tygodnia: [https://www.if.pw.edu.pl/~majanik/wiki/index.php/J%C4%99zyki_Programowania_5 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. |
Latest revision as of 09:06, 28 October 2025
Zadanie przykładowe.
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.