From MJanik
(Difference between revisions)
|
|
| (5 intermediate revisions not shown) |
| Line 1: |
Line 1: |
| | + | [https://www.if.pw.edu.pl/~majanik/data/JP/2025/Zadanie6_Biblioteka2.pdf Zadanie 6] - Biblioteka c.d. |
| | | | |
| | + | |
| | + | <hr /> |
| | | | |
| | Zadanie przykładowe. | | Zadanie przykładowe. |
| | | | |
| - | 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].
| + | == 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: [https://www.if.pw.edu.pl/~majanik/wiki/index.php/J%C4%99zyki_Programowania_5 Klasy pracownik, samochod]. |
| | | | |
| | == 1. Krok pierwszy: funkcje zaprzyjaźnione == | | == 1. Krok pierwszy: funkcje zaprzyjaźnione == |
| Line 72: |
Line 154: |
| | '''Informacje dodatkowe: Zaslanianie nazw''' | | '''Informacje dodatkowe: Zaslanianie nazw''' |
| | - Mozna, ale raczej utrudnia zycie, wiec unikamy. | | - Mozna, ale raczej utrudnia zycie, wiec unikamy. |
| - |
| |
| - |
| |
| - |
| |
| - | == Konstruktory ==
| |
| - |
| |
| - |
| |
| - | '''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ść.
| |
Latest revision as of 08:40, 7 November 2025
Zadanie 6 - Biblioteka c.d.
Zadanie przykładowe.
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ż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.