00001 /* 00002 Name: DL programowanie zadanie 12 z rozdziału 16 książki Thinking in C++ 00003 Author: Piotr Leżoń 00004 Date: 27-06-06 19:28 00005 Description: zadaniem było wykorzystanie jakos wewnętrznej implementacji klasy Stack klasy vector 00006 */ 00007 //: C16:TStack2.h 00008 // From Thinking in C++, 2nd Edition 00009 // Available at http://www.BruceEckel.com 00010 // (c) Bruce Eckel 2000 00011 // Copyright notice in Copyright.txt 00012 // Templatized Stack with nested iterator 00013 #ifndef TSTACK2_H 00014 #define TSTACK2_H 00015 00016 #include <vector> 00017 #include "require.h" 00018 00019 using namespace std; 00020 00021 template<class T> class Stack 00022 { 00023 vector<T*> v; //jako wewnetrzna implementacje wykorzystujemy klase vector 00024 public: 00025 Stack() : v(0) {} //konstruktor, tworzy wektor o zerowej dlugosci 00026 ~Stack(); //destruktor 00027 void push(T* dat) //metoda dodajaca element na koniec wektora 00028 { 00029 v.push_back(dat); //dodajemy do wektora element 00030 //head = new Link(dat, head); 00031 } 00032 T* peek() const 00033 { 00034 return 0;//head ? head->data : 0; 00035 } 00036 T* pop(); //metoda sciagajaca element 00037 // Nested iterator class: 00038 /*Podczas tworzenia zagnieżdżonej, zaprzyjaźnionej (friend) klasy należy najpierw zadeklarować jej 00039 nazwę, następnie zadeklarować ją jako klasę zaprzyjaźnioną, a dopiero potem zdefiniować samą klasę*/ 00040 class iterator; //deklarujemy 00041 friend class iterator; //zaprzyjazniamy 00042 class iterator //zagniezdzona, zaprzyjazniona klasa 00043 { //definicja klasy iterator 00044 Stack& itS; //przezywamy Stack jako itS 00045 int index; //potrzebny w iteratorze jako licznik, wskazuje pozycje iteratora 00046 public: 00047 iterator( Stack<T>& tl) : itS(tl), index(0){} //konstruktor domyslny, ustawia indeks na pierwszy element wektora 00048 // Copy-constructor: 00049 00050 iterator(const iterator& tl) : itS(tl.itS), index(tl.index){} //konstruktor kopiujacy, ustawia indeks na wskazany element wektora 00051 00052 //The end sentinel iterator: 00053 iterator( Stack<T>& tl, bool) : itS(tl), index(tl.v.end()+1){} //konstruktor wskazujacy na koniec wektora 00054 00055 // operator++ returns boolean indicating end: 00056 bool operator++() //operator sluzacy do przechodzenia po kolejnych elementach obiektu klasy vector 00057 { 00058 //if(index<itS.v.size()) //jesli index jest mniejszy od rozmiaru wektora, inkrementujemy go if(index<itS.v.size()-1) 00059 //index++; 00060 //else index = 0; //w przeciwnym razie zerujemy indeks - wyszedl poza zakres 00061 //return bool(index); 00062 return (bool) itS.v[index++]; //zwracamy logiczna wartosc konca 00063 } 00064 00065 bool operator++(int) { return (bool) itS.v[++index]; } //operator preinkrementacji 00066 00067 T* current() const /*Funkcja składowa current( ) zwraca wskaznik na element kontenera, który jest aktualnie wybrany przez iterator*/ 00068 { 00069 return itS.v[index]; //zwracamy wskaznik na konkretny element wektora 00070 } 00071 00072 // Pointer dereference operator: //operator wyluskania zwracajacy wskaznik na podany typ T 00073 T* operator->() const 00074 { 00075 require(index != 0, "Stack::iterator::operator->returns 0"); 00076 return current(); 00077 } 00078 T* operator*() const { return current(); } //kolejny operator sluzacy do uzyskania dostepu do konkretnego elementu w naszym wektorze 00079 // bool conversion for conditional test: 00080 operator bool() const { return bool(index); } //zwracamy wartosc logiczna 00081 // Comparison to test for end: 00082 bool operator==(const iterator&) const //operator porownania 00083 { 00084 return index == 0; 00085 } 00086 bool operator!=(const iterator&) const 00087 { 00088 return index != 0; 00089 } 00090 }; 00091 iterator begin() 00092 { 00093 return iterator(*this); 00094 } 00095 iterator end() 00096 { 00097 //return 0; 00098 return iterator(*this); 00099 } 00100 /*start i end są dwoma iteratorami, wyznaczającymi zakres. Iterator 00101 end, nazywany jest często wartownikiem albo znacznikiem końca (ang. end sentinel), 00102 nie jest wyłuskiwany; informuje nas jedynie, że znajdujemy się już na końcu sekwencji. 00103 Tak więc reprezentuje on „element następny po ostatnim".*/ 00104 }; 00105 00106 template<class T> Stack<T>::~Stack() { 00107 v.resize(0); 00108 } 00109 00110 template<class T> T* Stack<T>::pop() 00111 { 00112 if(!v.empty()) //jezeli obiekt nie jest pusty 00113 { 00114 v.pop_back(); 00115 //v.resize(v.end()-2); 00116 //v.erase(v.end()--); //czyscimy 00117 } 00118 } 00119 #endif // TSTACK2_H