1 / 37

Strumienie wejścia/wyjścia

Strumienie wejścia/wyjścia. ios istream ostream ifstream iostream ofstream istrstream istringstrem ostrstream ostringstream fstream strstream streambuf filebuf stdiobuf strstrambuf stringmbuf. Klasa ios.

Download Presentation

Strumienie wejścia/wyjścia

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Strumienie wejścia/wyjścia • ios • istream ostream • ifstream iostream ofstream • istrstream istringstrem ostrstream ostringstream • fstream strstream • streambuf • filebuf stdiobuf • strstrambuf stringmbuf Programowanie C++

  2. Klasa ios • class ios { • public: • typedef unsigned long fmtflags; // 32-bitowy łańcuch bitowy • typedef unsigned char iostate; // 8-bitowy łańcuch bitowy • protected: • streambuf* _strbuf; // wskaźnik do bufora • ostream* _tie; // wskaźnik do ostream dołączonego do istream • int _width; // szerokość pola wyjściowego • int _prec; // dokładność dla float • char _fill; // znak wypełnienia pustych pól • fmtflags _flags; // flagi formatowania • iostate _state; // aktualny stan io • ios(streambuf* _strbuf = 0, ostream* _tie = 0); X • ~ios(); • ... • }; _width _prec _fill _flags _state _strbuf _tie 15 9 ’#’ 03240 03 Programowanie C++

  3. Flagi formatowania • class ios { • public: • enum { skipws = 01, // pomiń białe znaki (domyślne) • left = 02, // wyrównanie lewostronne • right = 04, // wyrównanie prawostronne (domyślne) • internal = 010, // wyrównanie lewo i prawostronne • dec = 020, // konwersja dziesiątkowa • oct = 040, // konwersja ósemkowa • hex = 0100, // konwersja szesnastkowa • showbase = 0200, // pokaż podstawę konwersji • showpoint = 0400, // pokaż kropkę dziesiętną • uppercase = 01000, // duże litery w zapisie liczb • showpos = 02000, // użyj + z liczbami dodatnimi • scientific = 04000, // użyj notacji naukowej dla float i double • fixed = 010000, // użyj notacji z kropką dziesiętną • unitbuf = 020000, // buforowanie... • stdio = 040000 }; // ...współpraca z stdio • ... • }; Programowanie C++

  4. Selektory klasy ios • class ios { • public: • streambuf* rdbuf () const { return _strbuf ; } • ostream* tie () const { return _tie; } • int width () const { return _width; } • int precision () const { return _prec; } • char fill () const { return _fill; } • long flags () const { return _flags; } • int rdstate () const { return _state; } • ... • }; main () { cout<<"cout.width = "<< cout.width( ) <<endl; cout<<"cout.precision = " << cout.precision( )<<endl; cout<<"cout.fill = "<< cout.fill( )<<endl; cout<<"cin.flags = "<<cin.flags()<<endl; cout<<"cout.flags = "<<cout.flags()<<endl; } cout.width = 0 cout.precision = 6 cout.fill = cin.flags = 1 cout.flags = 200041 Programowanie C++

  5. Modyfikatory klasy ios • class ios { • public: • int width (int w) { int t = _width; _width = w; return t; } • int precision (int p) {int t = _precision; _precision = t; return t; } • char fill (char c) { char t = _fill; _fill = c; return t; } • long flags (long f) { long t = _flags; _flags = f; return t; } • ... • }; main () { cout.fill('#'); cout.width(40); cout<<"Hello World"<<endl; cout<<"Hello World"<<endl; double pi =3.14159265358979323946; cout<<" pi = "<<pi<<endl; cout.precision(16); cout<<" pi = "<<pi<<endl; cout<<" pi = "<<pi<<endl; cout.precision(20); cout<<" pi = "<<pi<<endl; } ############################Hello World Hello World pi = 3.141593 pi = 3.1415926535897931 pi = 3.1415926535897931 pi = 3.1415926535897931599 Programowanie C++

  6. Zmiana flag formatowania • main () • { • int n = 234; • long oldf = cout.flags(ios::hex | ios::uppercase); • cout<<n<<endl; • cout.flags(ios::hex | ios::showbase); • cout<<n<<endl; • cout.flags(oldf); • cout<<n<<endl; • } • class ios { • public: • long setf (long f) ; • long setf( long f, long mask); • long unsetf(long mask); • ... • }; EA 0xea 234 main () { int n = 234; long oldf = cout.setf (ios::hex | ios::uppercase); cout<<n<<endl; cout.setf (ios::hex | ios::showbase); cout<<n<<endl; cout.flags (oldf); cout<<n<<endl; } EA 0xEA 234 Programowanie C++

  7. Maski flag formatu main () { int n = 234; cout.setf(ios::hex | ios::uppercase| ios::showbase); cout<<n<<endl; cout.setf(ios::oct | ios::basefield); cout<<n<<endl; } • class ios { • public: • const long basefield = dec | oct | hex; • const long adjustfield = left | rigth | internal; • const long floatfield = scientific | fixed; • ... • }; main () { char buffer[80]; cin.unsetf(ios::skipws); //czyści domyślneustawienie flagi cin>>buffer; cout<<"["<<buffer<<"]\n"; cin>>buffer; cout<<"["<<buffer<<"]\n"; cin>>buffer; cout<<"["<<buffer<<"]\n"; int n = 234; cout.setf(ios::hex | ios::uppercase| ios::showbase; cout<<n<<endl; cout.usetf( ios::basefield); cout<<n<<endl; } 0XEA 0352 Hello, World. [ ] [ Hello,] [ World.] 0XEA 234 Programowanie C++

  8. Zmienne stanu klasy ios • class ios { • public: • enum { goodbit = 0, // wszystko ok • eofbit = 01, // koniec pliku • failbit = 02, // ostatnia operacja zakończona niepomyślnie • badbit = 04 }; // niewłaściwa operacja • ... • }; Dostępne selektory: good(), eof(), fail(), bad(), rdstate() main () { cout<<" cin.rdstate = "<<cin.rdstate()<<endl; int n; cin>>n; cout<<" cin.rdstate = "<<cin.rdstate()<<endl; } cin.rdstate = 0 22 cin.rdstate = 0 cin.rdstate = 0 ^Z cin.rdstate = 3 Programowanie C++

  9. Operatory dla stanu ios • class ios { • public: • operator void* () const; //operator konwersji • int operator! () const; • void clear (int ); // modyfikator - ustawia nowe słowo stanu strumienia • ... • }; main () { int n, sum=0; cin>>n; while (cin) { // pętla będzie wykonywana tak długo dopóki _state ==0 sum+=n; cin>>n; } cout<<" suma częściowa wynosi "<<sum<<endl; cin.clear(); while (cin>>n) sum+=n; cout<<" suma całkowita wynosi "<<sum<<endl; } 40 90 20 ^Z suma częściowa wynosi 150 30 50 ^Z suma całkowita wynosi 230 Programowanie C++

  10. Klasa istream • class istream : virtual public ios { // ...} zdefiniowanie ios jako wirtualnej klasy bazowej • ułatwia wielokrotne dziedziczenie, które • posiada klasa iostream • Strumień cin oraz operator >> klasy istream obsługują formatowane operacje wejścia. • Nieformatowane funkcje wejścia: • int get ( ); • istream& get ( char& c ); • istream& get ( char* buffer, int n, char delim = ’\n’ ); • istream& getline ( char* buffer, int n, char delim = ’\n’); • istream& ignore ( int n = 1, int delim = EOF); • int peek ( ); • istream& putback (char c); • istream& read ( char* buffer, int n); • istream& read ( unsigned char* buffer, int n); • int gcount ( ); Programowanie C++

  11. Nieformatowane wejście Litwo! Ojczyzno moja Litwo!Ojczyzno moja Ty jesteś jak zdrowie... Ty jesteś jak zdrowie... ^Z • main () • { • char c; • while((c = cin.get() ) != EOF) • cout<<c; • cout<<endl; • } Litwo! Ojczyzno moja Litwo!Ojczyzno moja Ty jesteś jak zdrowie... Ty jesteś jak zdrowie... ^Z main () { char c; while(cin.get (c) ) cout<<c; cout<<endl; } main () { char buffer[80]; cin.get(buffer,8); cout<<buffer<<endl; cin.get(buffer, sizeof(buffer)); cout<<buffer<<endl; cin.get(buffer,sizeof(buffer),'.'); cout<<buffer<<endl; } Litwo! Ojczyzno moja Litwo! Ojczyzno moja Ty jesteś jak zdrowie... Ty jesteś jak zdrowie Programowanie C++

  12. Nieformatowane wejście c.d. main () { char buffer[80]; cin.getline(buffer,8); cout<<buffer<<endl; cin.getline(buffer, sizeof(buffer)); cout<<buffer<<endl; cin.getline(buffer,sizeof(buffer),'.'); cout<<buffer<<endl; } Litwo! Ojczyzno moja Litwo! Ojczyzno moja Ty jesteś jak zdrowie... Ty jesteś jak zdrowie • main () • { • int month,year; • cout<<"Podaj datę (mm/dd/rrrr): "; • cin>>month; • cin.ignore(); // zjada '/' • cin.ignore(80,'/'); //zjada "dd/", lub "d/" lub "/" • cin>>year; • cout<<"Miesiąc = "<<month<<”, Rok = "<<year <<endl; • } Podaj datę (mm/dd/rrrr): 1/10/2000 Miesiąc = 1, Rok = 2000 Programowanie C++

  13. Nieformatowane wejście c.d. main () { char buffer[80],c ; cout<<cin.peek( ) <<" , "<< cin.peek( ) <<" ,"; c = cin.peek( ); cout<<c<<", "; cin.get(buffer, 5); c = cin.peek( ); cout<<c <<" , "<< cin.peek( ) <<" , "<< cin.peek( ) <<endl; cin.putback('Z'); cin.putback('Y'); cin.get(buffer,5); cout<<buffer<<endl; } • main () • { • char buffer[] = "????????????????????"; • cin.read(buffer, 8); • cout<<buffer<<" read: "<<cin.gcount( ) <<endl; • cin.read(buffer, 4); • cout<<buffer<<" read: "<<cin.gcount( ) <<endl; • } ABCDEFG 65, 65, A, E, 69, 69 YZEF ABCDEFGHIJKLMN ABCDEFGH???????????? read: 8 IJKLEFGH???????????? read: 4 Programowanie C++

  14. Klasa ostream • class ostream : virtual public ios { // ...} • Strumienie: cout // standardowe urządzenie wyjścia • cerr // standardowe urządzenie wyjścia dla komunikatów błędów (niebuforowany) • clog // jak wyżej, strumień buforowany • wraz z operatorem << obsługują formatowane wyjście. • Nieformatowane funkcje wyjścia: • int put ( char c ); • ostream& put ( char c ); • ostream& write ( const char* buffer, int n); • ostream& write ( const unsigned char* buffer, int n ); Programowanie C++

  15. Nieformatowane wyjście • main () • { • char c ; • while(cin.get (c) ) • cout.put(c); • cout<<endl; • cout.put('H'). put('e'). put('l'). put('l'). put('o'). put('\n'); • cout.write("ABCDEFGHIJKLMNOPRSTUWXYZ",8); • cout<<endl; • cout.write("1234567890", 4); • cout<<endl; • } Litwo! Ojczyzno moja Litwo!Ojczyzno moja Ty jesteś jak zdrowie... Ty jesteś jak zdrowie... ^Z Hello ABCDEF 1234 Programowanie C++

  16. Manipulatory strumieni • Najbardziej popularne manipulatory strumieni: Programowanie C++

  17. Definiowanie manipulatorów • Manipulatory strumieni definiowane są zgodnie z następującymi prototypami: • - manipulatory bezparametrowe • ios& f( ios& ostr); • ostream& f( ostream& ostr ); • istream& f ( istream& istr); • - manipulatory z parametrem • ios& f( ios& ostr , int n ); • ostream& f( ostream& ostr , int n ); • istream& f ( istream& istr , int n ); ostream& beep(ostream& ostr) { return ostr<<„\a”; } main ( ) { cout<<beep; } Programowanie C++

  18. Operacje wejścia/wyjścia na plikach • Otwarcia plików wejściowych i wyjściowych można dokonać za pomocą • konstruktorów lub funkcji open (mają takie same parametry): • void open ( char* name, int mode = ***, int prot = filebuf::openprot ); • Tryby otwarcia plików: Programowanie C++

  19. Wskaźnik pozycji w pliku • Każdy plik posiada swój wskaźnik (albo do czytania, albo do pisania, albo dwa niezależne wskaźniki jeden do czytania a drugi do pisania). Wskaźniki te są typu streampos • streampos tellg( ); // funkcja klasy istream pokazuje jakie jest położenie wskaźnika do czytania • streampos tellp( ); // funkcja klasy ostream pokazuje położenie wskaźnika pisania • enum seek_dir // typ wyliczeniowy zdefiniowany w klasie ios określający punkt odniesienia • { beg, // początek • cur, // aktualna pozycja • end }; // koniec • istream& seekg (streampos, seek_dir = ios::beg); • ostream& seekp(streampos, seek_dir = ios::beg); • Plik w C++ może być otwarty jednocześnie do zapisu i oczytu. Korzystamy wówczas z klasy fstream: • fstream strum(„plik.txt”, ios::in | ios::out) Programowanie C++

  20. Funkcje wirtualne main () { DatePolish today; DatePolish::SetFormat(DatePolish::TEXT); cout<<„\n Funkcja Write : „; today.Write(); cout<<„\n Funkcja Display ; „; today.Display; Date tomrrow(2000,1,11); tomorow.Display(); cout<<„\n Funkcja Display ; „; tomorow.Display(); ; } • class Date { • ... • virtual Write (ostream& output = cout) const • ... • }; Funkcja Write : 10 Styczeń 2000 Funkcja Display : 10 1 2000 Funkcja Display: 11 1 2000 Funkcja Write : 10 Styczeń 2000 Funkcja Display : 10 Styczeń 2000 Funkcja Display : 11 1 2000 Funkcje wirtualne gwarantują tzw. dynamiczne wiązanie czyli wywołanie funkcji jest odłożone do czasu realizacji programu i jest zależne od obiektu, na rzecz którego dana funkcja jest wywoływana. Programowanie C++

  21. Polimorfizm • Polimorfizm - pozwala by obiekty różnych typów powodowały różne działanie w wywołaniu tej samej funkcji. Jest to możliwe dzięki temu, że wskaźnik do obiektu klasy bazowej może również pokazywać na obiekty klas pochodnych. • Aby uzyskać wiązanie dynamiczne parametry muszą być przekazywane przez wskaźnik bądź referencję • Słowo virtual pojawia się tylko w deklaracji funkcji w klasie podstawowej, nie musi pojawić w klasie pochodnej • Jeśli klasa bazowa deklaruje funkcję wirtualną to musi zawierać jej definicję nawet jeśli ciało funkcji jest puste • Klasa pochodna nie musi definiować ponownie funkcji wirtualnej, wówczas domyślnie wywoływana jest funkcja z klasy bazowej • Klasa pochodna we własnej definicji nie może zmieniać typu zwracanego przez funkcję wirtualną Programowanie C++

  22. Wirtualne destruktory • Destruktory definiujemy jako funkcje wirtualne! class X { private: int* p; public: X() {p = new int[2]; cout<<” X(). ”;} ~X() { delete [] p; cout<<”~X (). \n”;} }; class Y: public X{ private: int* q; public: Y() {q = new int[100]; cout<<”Y() : Y::q = ”<<q<<”. ”;} ~Y() { delete [] q; cout<<”~Y() ”;} }; main ( ) { for (int i = 0; i<3; i++) { X* r = new Y; delete r; } X (). Y() : Y::q = 0x0d18. ~X(). X (). Y() : Y::q = 0x0de4. ~X(). X (). Y() : Y::q = 0x0eb0. ~X(). X (). Y() : Y::q = 0x0d24. ~Y() ~X(). X (). Y() : Y::q = 0x0d24. ~Y() ~X(). X (). Y() : Y::q = 0x0d24. ~Y() ~X(). virtual ~X() { delete [] p; cout<<”~X (). \n”;} Programowanie C++

  23. Czyste funkcje wirtualne i klasy abstrakcyjne • Media Audio Book Periodical CD Tape Record Magazine Newspaper Journal class Media{ protected: String title; public: virtual void print( ) = 0; virtual char* id( ) = 0; }; class Book: public Media{ private: String author, publisher,isbn; public: void print ( ) { cout<<title<<" by "<<author;} void id ( ) { cout<<isbn; } }; Czysta funkcja wirtualna - funkcja nie mająca w swojej klasie implementacji. virtual void f( ) = 0; Abstrakcyjna klasa bazowa - klasa posiadająca jedną lub więcej czystych funkcji wirtualnych. Programowanie C++

  24. Szablony funkcji • Szablon - abstrakcyjny przepis na tworzenie konkretnego kodu. • T jest parametrem szablonu • Szablon musi być zdefiniowany w zakresie globalnym. void swap( int& n, int& m) { int temp = n; n = m; m = temp; } void swap(Date& d1, Date& d2) { Date temp = d1; d1 = d2; d2 = temp; } template <class T> void swap(T& x, T& y) { T temp = x; x = y; y = temp; } main ( ) { int m = 22, n = 33; cout<<" m = "<<m<<" n = "<<n<<endl; swap(m,n); cout<<" m = "<<m<<" n = "<<n<<endl; Date d1,d2(1999,9,9); cout<<"d1 = "<<d1<<" d2 = "<<d2<<endl; swap(d1,d2); cout<<"d1 = "<<d1<<" d2 = "<<d2<<endl; } m = 22 n = 33 m = 33 n = 22 d1 = 2000 1 17 d2 = 1999 9 9 d1 = 1999 9 9 d2 = 2000 1 17 Programowanie C++

  25. Szablony klas • Szablony klas działają jak szablony funkcji generując klasy. • template <class T,...> class X {...}; • Funkcje składowe szablonu klasy są szablonami funkcji o takim samym nagłówku • jak szablon klasy. template <class T, int n> class X{}; main( ) { X <float, 22> x1; //O.K. const int n = 44; X<char, n> x2; //O.K. int m = 66; X <short, m> x3; //ERROR } template <class T> class X { T square (T t) { return t*t; } }; template <class T> T square (T t) { return t*t; } Programowanie C++

  26. Szablon klasy stos • template <class T> • class Stack { • private: • int size; • int top; • T* data; • public: • Stack( int s = 100): size(s); top = -1; { data = new T[size]; } • ~Stack( ) {delete [ ] data}; • void push (const T& x) {data[++top] = x; } • T pop() { return data[top--];} • int isEmpty( ) const {return top = = -1;} • int isFull( ) const { return top = = size - 1; } • }; main ( ) { Stack<int> stosint(5); Stack<Data> stosdata(10); Data x, y(2000,1,17); stosint.push(13); stosint.push(2); stosdata.push(x); stosdata.push(y); cout<<stosint.pop( )<<„ „<<stosint.pop( )<<endl; stosdata.pop( ).Display( ); } 2 13 2000 1 17 Programowanie C++

  27. Pojemniki • Pojemnik to obiekt, który zawiera inne obiekty (np.tablica, stos). • Klasa pojemnikowa (klasa - pojemnik) to klasa, której obiekty są pojemnikami. • Pojemnik zwany jest homogenicznym jeśli wszystkie jego obiekty są tego samego • typu lub heterogenicznym w przeciwnym przypadku. template <class T> class Vector{ protected: T* data; unsigned size; void copy(const Vector<T>&); public: Vector (unsigned n = 10) : size(n), data( new T[size]) { } Vector ( const Vector<T>& other) : size(other.size), data( new T[size]) { copy(other); } ~Vector {delete [ ] data;} Vector<T>& operator = (const Vector<T>&); T& operator [ ] (unsigned i) const {return data[ i ];} usigned Size( ) const {return size;} }; Programowanie C++

  28. Definicja funkcji składowych • template <classT> • Vector<T>& Vector<T>::operator = (const Vector<T>& other) • { • size = other.size; • data = new T[size]; • copy( other); • return this*; • } • template <class T> • void Vector<T>::copy( const Vector<T>& other) • { • unsigned min_size = (size < other.size ? size : other.size); • for (int i =0; i<min_size; i++) • data[i] = other.data[i]; • } Vector<short> v; v[5] = 34; Vector<short> w = v, x(3); cout<<w.size( ); Programowanie C++

  29. Dziedziczenie szablonów • Dziedziczenie szablonów klas działa tak samo jak dziedziczenie zwykłych klas. template <class T> class Array : public Vector<T>{ protected: int i0; public: Array(int i, int j): i0(i), Vector<T>(j-i+1) { } Array(const Array<T>& other): i0(other.i0), Vector<T>(other) { } T& operator [ ] (int i) const { return Vector<T>::operator [ ] (i-i0); } int firstSubscript( ) const { return i0;} int lastSubscript ( ) const { return i0+size - j; } }; #include<iostream.h> #include "Array.h" main ( ) { Array<float> x(1,3); x[1] = 2.22; x[2] = 3.33; x[3] = 4.44; cout<"x.Size( ) = "<<x.Size( )<<endl; cout<<x.fistSubscript( )<<".."<<lastSubscript( )<<endl; for (int i = 1, i<=3, i++) cout<<"x["<<i<<"] = "<<x[i]<<endl; } x.Size( ) = 3 1..3 x[1] = 2.22 x[2] = 3.33 x[3] = 4.44 Programowanie C++

  30. Szablony jako parametry szablonów • Ponieważ szablony klas pracują jak zwykłe klasy to można je przekazywać jako • parametry innych szablonów. Stack <Vector<int> > a; template <class T > class Matrix{ protected: Vector<Vector<T>*> row; public: Matrix( unsigned r =1, unsigned c=1) : row { for (int i=0; i<r; i++) row[i] = new Vector<T> (c); } ~Matrix () { for (int i = 0; i<row.size(); i++) delete row[i]; } Vector<T>& operator [ ](unsigned i) const { return *row[i]; } unsigned rows() { return row.size( ) } unsigned columns () { return row[0] -> size( ); } }; main ( ) { Matrix<float> a(2,3); a[0][0] = 0.0; a[0][1] = 0.1; a[0][2] = 0.2; a[1][0] = 1.0; a[1][1] = 1.1; a[1][2] = 1.2; cout<<"Macierz ma "<<a.rows( )<<" wiersze i " <<a.columns( ) <<" kolumny.\n"; for (int i=0; i<2; i++) { for (int j=0; j<3; j++) cout<<a[i][j]<<" "; cout<<endl; } } Macierz ma 2 wiersze i 3 kolumny 0.0 0.1 0.2 1.0 1.1 1.2 Programowanie C++

  31. Szablon klasy dla list jednokierunkowych • Listy - struktury pozwalające na dynamiczną alokację pamięci, tworzone jako połączony ciąg węzłów, z których każdy zawiera dane składowe oraz wskaźnik do następnego węzła. data 12 t template <class T> class ListNode { friend class List<T>; protected: T data; ListNode* next; public: ListNode(T& t, ListNode<T>* p): data(t), next(p) { } }; 12 p next int ListNode< int > template <class T> class List { protected: ListNode<T>* first; ListNode<T>* newNode( T& t, ListNode<T>* p) { ListNode<T>* q = new ListNode<T>(t,p); return q; } ... Programowanie C++

  32. Funkcje składowe szablonu listy ... public : List ( ) : first(0) { } ~List ( ); void insert (T t); int remove (T& t); int isEmpty ( ) { return first == 0;} void print ( ); }; • Konstruktor domyślny ustawia wskaźnikfirstna 0 • Destruktor będzie likwidował całą listę: template <class T> List <T>::~List ( ) { ListNode<T>* temp; for (ListNode<T>* p = first; p; ) { temp = p; p = p->next; delete temp; } } Funkcja insert tworzy nowy węzeł i wstawia go na początek listy: template <class T> void List <T>::insert (T t) { ListNode<T>* p = newNode(t,first); first = p; } Programowanie C++

  33. Listy c.d. #include <iostream.h> #include "List.h" main( ) { List<int> liczby; liczby.insert(0); liczby.insert(1); liczby.insert(2); liczby.insert(3); liczby.print( ); int x; liczby.remove(x); cout<<"Usunięto "<<x<<endl; liczby.print( ); } template <class T> int List <T>::remove ( T& t) { if (isEmpty()) return 0; t = first->data; ListNode<T>* p = first; first = first->next; delete p; return 1; } template <class T> void List <T>::print ( ) { for (ListNode<T>* p = first; p; p = p ->next) cout<<p -> data << "-> ”; cout<<”* \n”; } 3 -> 2 -> 1 -> 0 -> * Usunięto 2 2 -> 1 -> 0 -> * data 2 data next 1 next data 0 next Programowanie C++

  34. Iteratory • Iterator - obiekt mający zdolność poruszania się po elementach pojemników; działający jak wskaźnik pokazujący w danym momencie jeden element należący do pojemnika. • Podstawowe operacje iteratora: • inicjalizacja iteratora na początkowej • pozycji pojemnika, • pobranie wartości danych znajdujących • się we wskazywanej pozycji , • zmiana wartości danych na określonej • pozycji, • określenie czy we wskazywanej przez • iterator pozycji znajduje się jakaś wartość, • przesunięcie do następnej pozycji pojemnika. // Iterator.h template <class T> class Iterator { public: virtual int reset( ) = 0; virtual T operator ( )( ) = 0; virtual void operator = (T t) = 0; virtual int operator ! ( ) = 0; virtual int operator ++( ) =0; }; Programowanie C++

  35. Szablon iteratora dla szablonu klasy List // plik ListIter.h #include ”List.h” #include ”Iterator.h” template <class T> class ListIter: public Iterator<T> { protected: ListNode<T>* current; ListNode<T>* previous; List<T>& list; public: ListIter(List<T>& l):list(l) {reset( );} virtual void reset( ) {previous = NULL; current = list.first;} virtual T operator ( ) ( ) {return current->data;} virtual void operator = (T t) {current->data=t;} virtual int operator ! ( ) ; virtual int operator ++( ) ; void insert (T t); void preInsert(T t); void remove( ); }; template <class T> int ListIter<T>::operator ! ( ) { if (current==NULL) if (previous==NULL) current=list.first; else current=previous->next; return (current!=NULL); } if (!it)... template <class T> int ListIter<T>::operator ++ ( ) { if (current==NULL) if (previous==NULL) current=list.first; else current=previous->next; else { previous=current; current=current->next; } return (current!=NULL); } for (it.reset(); !it; it++)... Programowanie C++

  36. #include "List.h" #include "ListIter.h" #include "Date.h" main( ) { List<Date> Daty; ListIter<Date> it(Daty); Date today; it.insert(today); today.Forth(); it++; it.insert(today); today.Back(); it++; it.insert(today); Daty.print(); Date my(1994,4,19); it.reset(); it++; it=my; it++; it.remove(); for (it.reset(); !it; it++) {Date temp=it(); temp.Forth(); it = temp; } Daty.print(); } template <class T> void ListIter<T>::insert(T t) { ListNode<T>* p=list.newNode(t,0); if (list.isEmpty( ) ) list.first=p; else { p->next= current->next; current->next=p; } } template <class T> void ListIter<T>:remove( ) { if (current==list.first) list.first = current->next; else previous->next= current->next; delete current; current = 0; } 2000 3 28 -> 2000 3 29 -> 2000 3 28 ->* 2000 3 29 -> 1994 4 20 ->* Programowanie C++

  37. Przyjaciel Listy // List.h template <class T> class List { friend class ListIter<T>; //.... }; template <class T> class ListNode { friend class List<T>; friend class ListIter<T>; //.... }; • Lista może posiadać więcej niż jeden iterator: • Iteratory są od siebie niezależne. List<float> list; ListIter<float> it1(list), it2(list),it3(list); it1.insert(11.01); it1++; it1.insert(22.02); it1++; it1.insert(33.03); for (it2.reset(); !it2; it2++) it2=10*it2; it3=it1; Programowanie C++

More Related