Iteratory

Iterator - obiekt umożliwiający wygodny dostęp sekwencyjny do elementów kontenera bez konieczności znajomości jego struktury

Rodzaje iteratorów:

iterator wejścia (tylko do odczytu) i wyjścia (tylko do modyfikacji)

iterator jednokierunkowy (operator ++) i dwukierunkowy (operator ++ i --)

iterator swobodnego dostępu - przypomina w użyciu wskaźnik, przeciąża dodatkowo operatory: +, +=, -, -=, []. <, >, <=, >=

Iterator początku kolekcji begin(), iterator końca kolekcji end()

Iterator poruszający się w odwrotnej kolejności: rbegin() i rend()

Algorytmy STL operujące na iteratorach

Pętla for zakresowa od C++11

int tab [] = {42, 3, 5}; // odczyt kolekcji for(auto x: tab) { cout << x << endl; } // modyfikacja kolekcji for(auto &x: tab) { x++; }

Ćwiczenie: Iteratory klasy Wektor

Rozszerz implementację szablonu klasy Wektor z poprzednich zajęć (plik wektor.h) dodając do niej obsługę iteratorów.
Klasa Wektor powinna udostępniać:

iterator o swobodnym dostępie (random access iterator) typu Wektor::iterator, który udostępnia operator it++ przesuwający iterator do następnego elementu sekwencji i operator *it wydobywający wskazywany element

metodę begin() zwracającą iterator bezpośredniego dostępu pokazujący na pierwszy element

metodę end() zwracająca iterator pokazujący za ostatnim elementem

W tym przypadku iterator swobodnego dostępu będzie po prostu wskaźnikiem typu T*. Wystarczy więc przezwać ten typ używając polecenia typedef lub using.

Napisz program, który przetestuje działanie iteratorów w klasie Wektor:

wypełnij wektor liczbami całkowitymi 1, 2, 3, 4 ....

wymieszaj zawartość wektora algorytmem random_shuffle()

wypisz zawartość wektora korzystając z pętli for zakresowej

Obsługa wyjątków

Obsługa wyjątkow

std::exception - klasa wyjątków biblioteki standardowej

Przykład:

try { int a=1; throw a; } catch(int b) { // wyjatek typu int } catch(...) { // wszystkie wyjatki }

Ćwiczenie: Wyjatkowe sytuacje klasy Wektor

W pliku nagłówkowym wyjatki.h zadeklaruj klasy wyjątków: Wyjatek, ZlyIndeksWektora i BrakPamieci i dodaj do szablonu klasy Wektor polecenia rzucające obiekty tych klas w razie zaistnienia sytuacji wyjątkowych.

Klasa Wyjatek, stanowi ogólną klasę wyjątków po której będą dziedziczyły wszystkie inne typy wyjątków. Klasa ta zawiera:

pole chronione typu string przechowujące komunikat o błędzie.
Komunikat ustawiany jest przez konstruktor, np. : throw Wyjatek(„Pojawil sie nieoczekiwany blad!”).

metodę publiczną Komunikat() zwracająca tekst komunikatu.

Klasa ZlyIndeksWektora dziedziczy po klasie Wyjatek.
Obiekt tej klasy będzie rzucany gdy podamy niepoprawny indeks tablicy (wektora).
Klasa zawiera publiczne pole typu całkowitego inicjowane przez konstruktor, przechowujące wartość złego indeksu.

Klasa BrakPamieci dziedziczy po klasie Wyjątek.
Obiekt tej klasy rzucamy gdy zabraknie pamięci przy zwiększaniu wektora.

W zależności od konfiguracji, operator new w przypadku wystąpienia błędu może także rzucać wyjątek. Można temu zapobiec wymuszając aby w przypadku błędu operator ten zwracał NULL. #include <new.h> int *a = new(std::nothrow) int[1]; if(a==0) throw "Brak pamieci";

Klasy BrakPamieci i ZlyIndeksWektora dziedziczą po klasie Wyjatek, więc:

przeciążają odpowiednie konstruktory pozwalające dodać komunikat o błędzie przy tworzeniu obiektu (obiekty każdej z tych klas powinny być inicjowane odpowiednim domyślnym komunikatem)

zasłaniają metodę Komunikat() zwracając tekst odpowiednio sformatowany z zależności od sytuacji (od typu obiektu).

Napisz program, który wywoła sytuacje wyjątkowe dla klasy Wektor i spowoduje rzucenie wyjątków ZlyIndeksWektora oraz BrakPamieci. Złap wyjątki i wypisz komunikat błedu.

Zadanie 9: Sortowanie liczb i słów

Napisz program, który posortuje liczby i wyrazy wprowadzone przez użytkownika.

Dane wejściowe:

użytkownik wprowadza dane w konsoli, podając kolejne linie tekstu

każda linia może zawierać dowolny ciąg znaków

jeśli linia zawiera poprawnie zapisaną liczbę rzeczywistą, jest traktowana jako wartość numeryczna (a nie jako napis) i zostaje zamieniona na wartość typu double

Zasady przetwarzania danych:

konwersja napisu na liczbę odbywa się za pomocą funkcji stod()

jeśli konwersja na double' za pomocą stod() zakończy się sukcesem, liczba jest dodawana do kolekcji liczb

jeśli konwersja nie powiedzie się (np. napis nie jest liczbą), funkcja rzuca wyjątek std::invalid_argument - wtedy linia trafia do kolekcji napisów

jeśli liczba wykracza poza zakres typu double (funkcja rzuca wyjątek std::out_of_range), linia jest ignorowana (nie trafia ani do liczb, ani do napisów)

Wynik działania programu:

Program przestaje wczytywać dane, gdy użytkownik wprowadzi pustą linię (długość napisu równa 0). Następnie program wypisuje:

wszystkie rozpoznane liczby posortowane w kolejności rosnącej

wszystkie pozostałe napisy posortowane alfabetycznie

Do kolekcjonowania napisów i liczb wykorzystaj klasę Wektor a do posortowania obu sekwencji wykorzystaj funkcję sort() z biblioteki STL.

Przykład działania programu:

Dla danych wejściowych

zxcvbn
1234
asdf
42
3.14
qwerty
10e100000
10e2

program wypisze

Liczby:
3.14
42
1000
1234
Napisy:
asdf
qwerty
zxcvbn

Rozwiązanie w postaci plików nagłówkowych *.h i źródłowych *.cpp umieść w Moodle Zadanie 9