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 (do odczytu) i wyjścia (do wstawiania)
    • 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};
 
for(auto x: tab) 
{
  cout << x << endl;
}
 
for(auto &x: tab) 
{
  x++;
}

Dodaj do szablonu klasy Wektor z poprzednich zajęć (plik wektor.h):

  • 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
  • metody begin() i end() zwracające iterator (bezpośredniego dostępu) pokazujący odpowiednio na pierwszy element oraz na pozycję 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 wektora 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

Przykład:

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

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 przechowujące komunikat o błędzie (string).
      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.

Napisz program, który dokona posortowania liczb i wyrazów podanych przez użytkownika. Dane wejściowe (liczby i wyrazy) podaje użytkownik w konsoli, wpisując kolejne linie tekstu, przy czym każda linia może zawierać dowolny ciąg znaków. Jeżeli podana linia tekstu zawiera poprawnie wyrażona liczbę rzeczywistą to wówczas traktowana jest jak wartość numeryczna a nie jako łańcuch znakowy. Napis zawierający liczbę zamieniany jest na wartość numeryczną za pomocą funkcji stod(). Jeżeli operacja zakończy sie powodzeniem, wówczas liczba umieszczana jest w kolekcji z liczbami. Jeżeli operacja się nie powiedzie, gdyż napis nie zawiera liczby (funkcja w tym wypadku rzuca wyjątek std::invalid_argument) to analizowana linia tekstu dodawana jest do kolekcji napisów. Jeżeli podana liczba wykracza poza zakres typu double (funkcja w tym wypadku rzuca wyjątek std::out_of_range) to linia jest ignorowana (nie jest traktowana ani jak liczba ani jak napis). Program kończy wczytywanie danych, gdy użytkownik wprowadzi pustą linię (tj. wczytany napis będzie miał długość 0). Po tym wypisywana jest sekwencja wszystkich rozpoznanych liczb w porządku rosnących wartości a nastepnie wypisywana jest sekwencja wszystkich pozostałych linii tekstu w porządku alfabetycznym. Do posortowania obu sekwencji wykorzystaj funkcję sort() z biblioteki STL.

Przykład działania programu:

zxcvbn
1234
asdf
42
3.14
qwerty
10e100000
10e2

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