Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Poprzednia wersja
Nowa wersja
Poprzednia wersja
pl:dydaktyka:jimp2:2017:labs:dziedziczenie [2018/04/18 14:45]
mwp [Funkcje wirtualne]
pl:dydaktyka:jimp2:2017:labs:dziedziczenie [2019/06/27 15:50] (aktualna)
Linia 364: Linia 364:
     // MUSI jednak być zaimplementowana w pochodnej (lub ponownie ​     // MUSI jednak być zaimplementowana w pochodnej (lub ponownie ​
     // zadeklarowana jako czysta     // zadeklarowana jako czysta
-    virtual double ​pobierzNetto() = 0;+    virtual double ​PobierzNetto() = 0;
 }; };
 </​code>​ </​code>​
Linia 476: Linia 476:
       * AndQuery <​code>​AndQuery(std::​unique_ptr<​Query>​ left, std::​unique_ptr<​Query>​ right)</​code>​       * AndQuery <​code>​AndQuery(std::​unique_ptr<​Query>​ left, std::​unique_ptr<​Query>​ right)</​code>​
   - [1 plus] Przetestuj przykład z sekcji [[#​metody_skladowe|Metody składowe]]   - [1 plus] Przetestuj przykład z sekcji [[#​metody_skladowe|Metody składowe]]
-  - **[1 punkt] Wykorzystując klasę [[.:​klasy1#​deklaracja_klasy|Punkt]],​ napisz klasę Punkt3D dziedziczącą po niej i implementującą dodatkowo metodę //double distance(Punkt3D)//​. W każdym z konstruktorów i destruktorów klas Punkt i Punkt3D wypisz na ekran jakąś wiadomość i zaobserwuj w jakiej kolejności wywołują się konstruktory i destruktory.** 
-  - **[1 punkt] Mając dwa obiekty, jeden klasy Punkt a drugi klasy Punkt3D o nazwach //punkt2d// i //​punkt3d//,​ wywołaj punkt2d.distance(punkt3d). Co sie stało?** 
-  - **[1 punkt] W klasie Punkt2D istnieje przeciążony operator wpisywania do strumienia ("<<"​). Co się stanie jeśli będziesz chciał wypisać obiekt klasy Punkt3D w następujący sposób:** <code cpp>​Punkt3D p3d(1,2,3); 
-cout << p3d << endl;</​code>​ 
   - [3 plusy] Napisz dwie klasy: Kolo i Kula. Klasa Kolo powinna być klasą bazową dla klasy Kula.   - [3 plusy] Napisz dwie klasy: Kolo i Kula. Klasa Kolo powinna być klasą bazową dla klasy Kula.
     * W klasie Kolo powinny znaleźć się następujące pola i metody:     * W klasie Kolo powinny znaleźć się następujące pola i metody:
Linia 498: Linia 494:
 </​code>​ </​code>​
   - [2 plusy] Dopisz brakujące metody z przykładu [[#​funkcje_wirtualne|Funkcje wirtualne]] i uruchom program.   - [2 plusy] Dopisz brakujące metody z przykładu [[#​funkcje_wirtualne|Funkcje wirtualne]] i uruchom program.
-  - **[2 punkty] Napisz klasę abstrakcyjną //​Ksztalt//,​ która będzie posiadała jedna czystą metodę wirtualną //rysuj//. Następnie napisz kilka klasę dziedziczących po tej klasie (//​Trójkąt,​ Kwadrat, Koło//) i odpowiednio implementujących metodę //rysuj//. Metoda powinna rysować kształty w trybie tekstowym. \\ Zadeklaruj listę, która przechowuje wskaźniki na obiekty klasy //Ksztalt// i uzupełnij ją losowo //Kolami, Kwadratami//​ albo //​Trojkatami//​. Następnie wywołaj na każdym obiekcie z listy metodę //rysuj//. Jaki jest tego efekt?** 
  
 +====== Zadanie domowe: ======
 +
 +Iteratory to uogólnienie wskaźników wykorzystywanych do iteratowania po tablicy. W c żeby przeiterować po tablicy i tylko odczytać jej elementy można było wykonać następujący kod:
 +<code c>
 +  int tab[128];
 +  int *p;
 +  int *tab_end = &​tab[128];​
 +  int value;
 +  InitTab(tab);​
 +  for (p = &​tab[0];​ p != tab_end; ++p) {
 +     value = *p;
 +  }
 +</​code>​
 +Wraz z c++ przyszły klasy i przeciążanie operatorów i w tym języku da się uogólnić ten schemat na dowolny obiekt, który posiada odpowiednioo zdefiniowane metody:
 +<code cpp>
 +  array<​int,​128>​ tab;
 +  array<​int,​128>::​iterator p;
 +  array<​int,​128>::​iterator tab_end = tab.end();
 +  int value;
 +  InitTab(tab);​
 +  for (p = tab.begin();​ p != tab_end; ++p) {
 +     value = *p;
 +  }
 +</​code>​
 +Ze względu na to, że kompilator udziela niezbyt jasnych informacji o błędach i o tym co jest niezbędne do zaimplementowania,​ spróbujemy wykorzystać dziedziczenie. W tym celu zdefiniujemy klasę bazową która mogłaby być wykorzystywana przez dowolną implementację iteratora:
 +  - **[1 punkt]** (lab7_iterable_tests) przygotować klasę bazową //​IterableIterator//​ udostępniającą następujący zestaw metod bez zdefiniowanego zachowania (abstrakcyjnych,​ czysto wirtualnych),​ wszystkie te metody mają być przesłanialne przez klasy pochodne, zastanowić się które z tych metod nie powinny modyfikować **this**:
 +    * <code cpp>​std::​pair<​int,​ std::​string>​ Dereference()</​code>​ - odpowiada operacji //cos = *it//, czyli jej implementacja w klasach pochodnych powinna zwracać wartość pokazywaną przez iterator w akutalnym stanie. Nie umożliwiamy edycji tego stanu, stąd wartość zwracana jest przez kopię, a nie referencję.
 +    * <code cpp>​IterableIterator &​Next()</​code>​ - odpowiada operacji //++it// jej implementacja w klasie pochodnej powinna przesuwać wskaźnik na następną wartość w sekwencji, jeśli nie ma następnej wartości powinna przesuwać wskaźnik tuż za koniec
 +    * <code cpp>bool NotEquals(const IterableIterator &​other)</​code>​ - odpowiada operacji //it != other//, jej implementacja w klasie pochodnej powinna zwracać prawdę jeśli iterator other wskazuje na ten sam element sekwencji (względnem jego indeksu w sekwencji, a nie tylko jego wartości zwracanej przez //​Dereference()//​).
 +    * Destruktor - jako jedyna metoda w tej klasie powinien mieć domyślną implementację,​ najlepiej skorzystać z pomocy kompilatora i kazać mu ją wygenerować (= defualt). ​
 +  - **rozgrzewka** Należy zaimplementować klasę pochodną dla **IterableIterator**,​ a mianowicie: **ZipperIterator**,​ zipper iterator powinien być w stanie przeiterować po dwóch wektorach na raz, biorąc po kolei pierwszy element z pierwszego wektora i pierwszy element z drugiego wektora, drugi element z pierwszego i drugi element z drugiego, itd.. Najłatwiej to zrobić jeśli ZipperIterator będzie posiadał po dwa const iteratory do początu i końca obu wektorów. Wtedy Derefencja, Next i NotEquals są bardzo proste w implementacji. (Testy wymagają konstuktora postaci: <code cpp>​explicit ZipperIterator(std::​vector<​int>::​const_iterator left_begin,
 +                 ​std::​vector<​std::​string>::​const_iterator right_begin,​
 +                 ​std::​vector<​int>::​const_iterator left_end,
 +                 ​std::​vector<​std::​string>::​const_iterator right_end);</​code>​
 +  - **[1 punkt]** przygotować ​
 +    - klasę IterableIteratorWrapper opakowującą dowloną podklasę IterableIterator i udostępniającą operatory i fukncje potrzebne by klasa mogła być używana jako iterator c++ między innymi w rage for, czyli (zastanowić się, które z tych funkcji muszą być typu const):
 +      * konstruktor:​ <code cpp>​IterableIteratorWrapper(std::​unique_ptr<​IterableIterator>​ iterator)</​code> ​
 +      * <code cpp>bool operator!=(const IterableIteratorWrapper &​other)</​code>​ - powinna wywoływać NotEquals z przekazanych iteratorach (pole składowe i argument fukncji)
 +      * <code cpp>​std::​pair<​int,​ std::​string>​ operator*()</​code>​ - powinna wywoływać Dereference na polu składowym
 +      * <code cpp>​IterableIteratorWrapper &​operator++()</​code>​ - powinna wywoływać Next na polu składowym
 +    - przygotować klasę bazową Iterable o następujących metodach (zastanowić się, które z tych funkcji muszą być typu const):
 +      * <code cpp>​std::​unique_ptr<​IterableIterator>​ ConstBegin()</​code>​ - czysto abstrakcyjna metoda (bez domyślnej implementacji) przesłanialna w klasach pochodnych ma za zadanie zwracanie odpowiedniego iteratora do początku sekwencji dla właściwej klasy.
 +      * <code cpp>​std::​unique_ptr<​IterableIterator>​ ConstEnd()</​code>​ - czysto abstrakcyjna metoda (bez domyślnej implementacji) przesłanialna w klasach pochodnych ma za zadanie zwracanie odpowiedniego iteratora za końcem sekwencji dla właściwej klasy.
 +      * <code cpp>​IterableIteratorWrapper cbegin() const</​code>​ - konkretna metoda (nie wirtualna), która wywołuje ConstBegin i tworzy odpowiedni typ do zwrócenia.
 +      * <code cpp>​IterableIteratorWrapper cend() const</​code>​ - konkretna metoda (nie wirtualna), która wywołuje ConstEnd i tworzy odpowiedni typ do zwrócenia.
 +      * <code cpp>​IterableIteratorWrapper begin() const</​code>​ - konkretna metoda (nie wirtualna), która wywołuje cbegin()
 +      * <code cpp>​IterableIteratorWrapper end() const</​code>​ - konkretna metoda (nie wirtualna), która wywołuje cend()
 +  - **[3 punkty]** (lab7_iterable_zipper_tests,​ lab7_iterable_product_tests,​ lab7_iterable_enumerate_tests)przygotować klasy Zipper, Product, Enumerate, które implementują klasę Iterable i klasy ProductIterator i EnumerateIterator,​ które implementują klasę IterableIterator.
 +    * klasa zipper ma za zadanie utworzenie możliwości przeglądania dwóch wektorów jednocześnie w pętli typu range for.
 +    * klasa enumerate ma za zadanie utworzenie możliwości przeglądania jednego wektora w pętli typu range for, ale tak, że każda wartość wskazywana przez jej iterator zwraca parę indeks tego elementu, wartość tego elementu.
 +    * klasa product ma za zadanie utworzenie możliwości przeglądania dwóch wektorów jednocześnie w pętli typu range for, ale w przeciwieństwie do zipper, ma tworzyć iloczy kartezjański wszystkich par <code cpp>
 +  const vector<​int>​ vi {4, 77, -91};
 +  const vector<​string>​ vs {"​4",​ "​9991",​ "​adfskld"​};​
 +
 +  for (const auto &p : Zipper(vi, vs)) {
 +    cout << "​("​ << p.first << ", \""​ << p.second << "​\"​) ";
 +  }
 +  //wypisze: (4, "​4"​) (77, "​9991"​) (-91,"​adfskld"​)
 +  ​
 +  for (const auto &p : Enumerate(vs)) {
 +    cout << "​("​ << p.first << ", \""​ << p.second << "​\"​) ";
 +  }
 +  //wypisze: (0, "​4"​) (1, "​9991"​) (2,"​adfskld"​)
 +  ​
 +  for (const auto &p : Product(vi,​vs)) {
 +    cout << "​("​ << p.first << ", \""​ << p.second << "​\"​) ";
 +  }
 +  //wypisze: (4, "​4"​) (4,"​9991"​) (4, "​adfskld"​) (77, "​4"​) (77,"​9991"​) (77, "​adfskld"​) (-91,"​4"​) (-91,"​9991"​) (-91, "​adfskld"​) ​
 +
 +</​code>​
pl/dydaktyka/jimp2/2017/labs/dziedziczenie.1524055508.txt.gz · ostatnio zmienione: 2019/06/27 15:52 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0