A szerdai csoportoknak ez a labor elmarad.
Órai dolgok
Az órán a 11. aut-os konzerv 2. feladatát oldottuk meg: lista osztálysablont készítettünk.12. Házi feladat.
Fejezzük be az órai feladatot! (Aki nagyon nem boldogul, kis segítség a lap legvégén.) Egészítsük ki iterátorral a lista osztályt, és a tesztelőben ezt használjuk. KészítsünkSList<T> concatenate(const SList<T> &) const
és SList<T> reverse() const
lista tagfüggvényt. Előbbi összefűzi a két listát, utóbbi megfordítja az egyet (paramétereihez egyik sem nyúl). Ehhez szükség van egy jól működő másoló ctor megvalósítására is, de csak átgondolva!
Az iterátor megvalósításához egy "kis" segítség. (Minden itt van, tessék megérteni, mit miért úgy.)
... template<class T> class SList; // Elore deklarálni kell a friend miatt template <class T> class ListElement { friend class SList<T>; //************************************************************************* friend class SList<T>::iterator; // hogy iterator is elerje pNext-et //************************************************************************* T data; ListElement* pNext; void operator=(const ListElement&) {} //!!!! hogy ne mukodhessen az automatikus op= ListElement(const ListElement&) {} //!!!! hogy ne mukodhessen az automatikus copy ctor public: ... }; template<class T> class SList { ... public: //************************************************************************* class iterator; // elodeklaracio //************************************************************************* // Létrehoz egy üres listát SList(); // Destruktor virtual ~SList(); ... // Visszaadja az utolsó elem utáni hely pozícióját // ez már nem használható fel!!! //************************************************************************* ListElement<T>* lend() { // at kell nevezni, vagy torolni, hogy ne legyen konfliktus return 0; } //************************************************************************* iterator begin() { // létrehoz egy iterátort és az elejére állítja return iterator(*this); } iterator end() { // létrehozza és az utolsó elem után állítja return iterator(); } //************************************************************************* ... /********************************************************************* class iterator { ListElement<T> *p; // pointer az akt elemre, és az utolsó utánira public: // Van benne pointer, mégis jó a default másoló konstruktor és az értékadó op. Miért ? iterator() :p(0) {} // default kontruktor iterator(SList& a) :p(a.pStart) {} // kontruktor SList-rol iterator& operator++() { // növeli az iterátort (pre) ++it if (p != 0) p=p->pNext; return *this; } iterator& operator++(int) { // növeli az iterátort (post) it++ (mindig int kell!) iterator tmp = *this; if (p != 0) p=p->pNext; return tmp; } bool operator!=(const iterator &i) { // összehasonlít return(p != i.p); } T& operator*() { // indirekció if (p != 0) return p->data; else throw std::runtime_error("Hibas indirekcio"); } T* operator->() { // indirekció if (p != 0) return p; else throw std::runtime_error("Hibas indirekcio"); } }; // iterator osztály vége ***********************************************************************/ }; // SList vegeÉs a tesztelőben a tipikus ciklus:
int main() { SList<int> intList; ... cout << "iteratorral:\n"; for(SList<int>::iterator it=intList.begin(); it!=intList.end(); ++it) cout << *it << " "; cout << endl; ... return 0; }Így kell kinéznie az órai feladatban két a tesztelőben gyakran hívott függvénynek:
template<class TYPE> POSITION SList<TYPE>::push_back(const TYPE& element) { ListElement<TYPE>**pCurrent; for(pCurrent=&pStart;*pCurrent!=endSymbol;pCurrent=&((*pCurrent)->pNext)); *pCurrent =new ListElement<TYPE>(element,endSymbol); return reinterpret_cast<POSITION>(*pCurrent); } template<class TYPE> TYPE SList<TYPE>::remove(POSITION position) { if(!position) throw runtime_error("null ptr in remove"); ListElement<TYPE>*pPosition =reinterpret_cast<ListElement<TYPE>*> (position); if(pPosition==pStart) { pStart=pPosition->pNext; } else { ListElement<TYPE>*pPrevious=reinterpret_cast<ListElement<TYPE>*> (previous(position)); pPrevious->pNext=pPosition->pNext; } TYPE element=pPosition->data; delete pPosition; return element; }include "../_foot.inc"; ?>