Vill c++ kisHF

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ünk SList<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;
	}