Zaawansowane CPP/Ćwiczenia 5: Klasy cech: Różnice pomiędzy wersjami
Nie podano opisu zmian |
Nie podano opisu zmian |
||
Linia 1: | Linia 1: | ||
W poprzednich rozdziałach przedstawiono mechanizm typów związanych | W poprzednich rozdziałach przedstawiono mechanizm typów związanych | ||
(czyli typedefów zagnieżdżonych wewnątrz klasy). | (czyli typedefów zagnieżdżonych wewnątrz klasy). | ||
Linia 8: | Linia 4: | ||
do pisania szablonów funkcji parametryzowanych typem iteratora (albo | do pisania szablonów funkcji parametryzowanych typem iteratora (albo | ||
pojemnika). | pojemnika). | ||
Zagnieżdżony wewnątrz tego typu typ związany <code><nowiki> value_type</nowiki></code> | Zagnieżdżony wewnątrz tego typu typ związany <code><nowiki>value_type</nowiki></code> pozwala na | ||
tworzenie pomocniczych zmiennych przechowujących przetwarzane wartości, | tworzenie pomocniczych zmiennych przechowujących przetwarzane wartości, | ||
<code><nowiki> iterator_category</nowiki></code> pozwala wybrać odpowiednią wersję kodu, | <code><nowiki>iterator_category</nowiki></code> pozwala wybrać odpowiednią wersję kodu, | ||
i tak dalej. | i tak dalej. | ||
Linia 16: | Linia 12: | ||
Po pierwsze, muszą być one podczepione pod klasę, a czasem możemy chcieć | Po pierwsze, muszą być one podczepione pod klasę, a czasem możemy chcieć | ||
uzyskać informacje na temat czegoś, co może być albo klasą, albo prostym | uzyskać informacje na temat czegoś, co może być albo klasą, albo prostym | ||
typem wbudowanym (patrz iteratory | typem wbudowanym (patrz iteratory - albo klasy, albo zwykłe wskaźniki). | ||
Po drugie, lista przekazywanych informacji jest zamknięta; aby | Po drugie, lista przekazywanych informacji jest zamknięta; aby | ||
coś dodać, trzeba mieć dostęp do kodu źródłowego i go zmodyfikować. | coś dodać, trzeba mieć dostęp do kodu źródłowego i go zmodyfikować. | ||
Linia 25: | Linia 21: | ||
i zwracającą najmniejszy z tego ciągu elementów. | i zwracającą najmniejszy z tego ciągu elementów. | ||
Najpierw opracuj wersję wykorzystującą typ związany, a potem wersję | Najpierw opracuj wersję wykorzystującą typ związany, a potem wersję | ||
korzystającą ze standardowego szablonu cechującego <code><nowiki> iterator_traits</nowiki></code> . | korzystającą ze standardowego szablonu cechującego <code><nowiki>iterator_traits</nowiki></code> . | ||
Sprawdź działanie obu wersji na liście oraz na zwykłej tablicy. | Sprawdź działanie obu wersji na liście oraz na zwykłej tablicy. | ||
Przypominajka: w obu przypadkach niezbędne będzie słówko kluczowe | Przypominajka: w obu przypadkach niezbędne będzie słówko kluczowe | ||
<code><nowiki> typename</nowiki></code> . | <code><nowiki>typename</nowiki></code> . | ||
'''Zadanie 2 ''' | '''Zadanie 2 ''' | ||
Zapoznaj się z plikiem <code><nowiki> kategorie.cpp</nowiki></code> . | Zapoznaj się z plikiem <code><nowiki>kategorie.cpp</nowiki></code> . | ||
Jest w nim przedstawiony sposób selekcji jednej spośród kilku implementacji | Jest w nim przedstawiony sposób selekcji jednej spośród kilku implementacji | ||
algorytmu na podstawie możliwości oferowanych przez przekazany iterator; | algorytmu na podstawie możliwości oferowanych przez przekazany iterator; | ||
Linia 52: | Linia 48: | ||
Ponieważ biblioteka standardowa nie dostarcza odpowiedniego mechanizmu, | Ponieważ biblioteka standardowa nie dostarcza odpowiedniego mechanizmu, | ||
trzeba go samodzielnie stworzyć. | trzeba go samodzielnie stworzyć. | ||
Zaimplementuj szablon cechujący o nazwie <code><nowiki> is_pointer</nowiki></code> , zawierający | Zaimplementuj szablon cechujący o nazwie <code><nowiki>is_pointer</nowiki></code> , zawierający | ||
składową boolowską <code><nowiki> value</nowiki></code> . | składową boolowską <code><nowiki>value</nowiki></code> . | ||
'''Podpowiedź do zadania 4 ''' | '''Podpowiedź do zadania 4 ''' | ||
Stwórz ogólny szablon zawsze zwracający <code><nowiki> false</nowiki></code> , a potem wyspecjalizuj | Stwórz ogólny szablon zawsze zwracający <code><nowiki>false</nowiki></code> , a potem wyspecjalizuj | ||
go dla typów będących wskaźnikiem do czegoś i tam zwracaj <code><nowiki> true</nowiki></code> . | go dla typów będących wskaźnikiem do czegoś i tam zwracaj <code><nowiki>true</nowiki></code> . | ||
'''Rozwiązanie 4 ''' | '''Rozwiązanie 4 ''' | ||
Patrz plik <code><nowiki> czy_wsk.cpp</nowiki></code> . | Patrz plik <code><nowiki>czy_wsk.cpp</nowiki></code> . |
Wersja z 09:25, 3 wrz 2006
W poprzednich rozdziałach przedstawiono mechanizm typów związanych
(czyli typedefów zagnieżdżonych wewnątrz klasy).
Jest on intensywnie wykorzystywany w STL, gdzie bardzo przydaje się
do pisania szablonów funkcji parametryzowanych typem iteratora (albo
pojemnika).
Zagnieżdżony wewnątrz tego typu typ związany value_type
pozwala na
tworzenie pomocniczych zmiennych przechowujących przetwarzane wartości,
iterator_category
pozwala wybrać odpowiednią wersję kodu,
i tak dalej.
Technika typów związanych ma jednak dwie wady. Po pierwsze, muszą być one podczepione pod klasę, a czasem możemy chcieć uzyskać informacje na temat czegoś, co może być albo klasą, albo prostym typem wbudowanym (patrz iteratory - albo klasy, albo zwykłe wskaźniki). Po drugie, lista przekazywanych informacji jest zamknięta; aby coś dodać, trzeba mieć dostęp do kodu źródłowego i go zmodyfikować. Rozwiązaniem obu problemów są szablony cechujące.
Zadanie 1
Zaimplementuj funkcję uogólnioną biorącą jako argumenty parę iteratorów,
i zwracającą najmniejszy z tego ciągu elementów.
Najpierw opracuj wersję wykorzystującą typ związany, a potem wersję
korzystającą ze standardowego szablonu cechującego iterator_traits
.
Sprawdź działanie obu wersji na liście oraz na zwykłej tablicy.
Przypominajka: w obu przypadkach niezbędne będzie słówko kluczowe
typename
.
Zadanie 2
Zapoznaj się z plikiem kategorie.cpp
.
Jest w nim przedstawiony sposób selekcji jednej spośród kilku implementacji
algorytmu na podstawie możliwości oferowanych przez przekazany iterator;
w tym konkretnym przykładzie rozróżniamy dwie grupy: iteratory o swobodnym
dostępie oraz wszystkie inne.
Rozszerz kod tak, aby wybierana była jedna z trzech możliwości: swobodny
dostęp, dwukierunkowe, gorsze niż dwukierunkowe.
Zadanie 3 Opierając się na przykładowym kodzie z poprzedniego zadania zaimplementuj wariantowy algorytm sortowania ciągów. Dla iteratorów jednokierunkowych użyj sortowania przez prosty wybór (patrz odpowiednie ćwiczenie w module 3); dla tych o dostępie swobodnym użyj quicksortu.
Zadanie 4
Do jakichś bliżej nie znanych celów potrzebny jest sposób na odróżnianie
iteratorów będących zwykłymi, klasycznymi wskaźnikami od wszystkich
pozostałych.
Ponieważ biblioteka standardowa nie dostarcza odpowiedniego mechanizmu,
trzeba go samodzielnie stworzyć.
Zaimplementuj szablon cechujący o nazwie is_pointer
, zawierający
składową boolowską value
.
Podpowiedź do zadania 4
Stwórz ogólny szablon zawsze zwracający false
, a potem wyspecjalizuj
go dla typów będących wskaźnikiem do czegoś i tam zwracaj true
.
Rozwiązanie 4
Patrz plik czy_wsk.cpp
.