Schneller Copy Konstruktor für einen Stack



  • den operator= und swap hab ich schon fertig, benutzte immer die C-tor+swap methode für operator=

    template<class T>void MyStack<T>::swap(MyStack &stck)
    {
    	int itemp = this->anzahl_elemente;
    	this->anzahl_elemente = stck.anzahl_elemente;
    	stck.anzahl_elemente = itemp;
    	Element *etemp = this->top;
    	this->top = stck.top;
    	stck.top = etemp;
    }
    
    template<class T>MyStack<T>& MyStack<T>::operator=(const MyStack& other)
    {
    	MyStack<T> temp = other;
    	this->swap(temp);
    	return *this;
    }
    

    welche header muss ich einbinden um std::swap zu benutzen?

    io das mit dem != operator war mir klar, bin ja nicht so doof alles neu zu schreiben, geht ja viel einfacher wenn ich den fertigen == operator schon hab, das gleiche mit > und <= , < und >=



  • uhsuhz schrieb:

    welche header muss ich einbinden um std::swap zu benutzen?

    <algorithm>



  • danke wieder was dazugelernt^^


  • Mod

    Den copy-ctor können wir eleganter schreiben, da alle notwendigen Operationen bereits in anderen Funktionen realisiert werden.

    template<class T>MyStack<T>::MyStack(const MyStack &other)
    :top(NULL), anzahl_elemente(0)
    {
        MyStack temp; // !!!
        for ( Element* p = other.top; p != NULL; p = p->next )
            temp.push( p->data );
        swap( temp );
    }
    

    sieht fast aus wie op= ? So ein Zufall 😉
    Bzgl. pop bin ich mir etwas unsicher:

    template<class T> T Stack<T>::pop()
    {
             if (! top) throw EmptyStackException();
             T result(top.data);
        Element* temp = top;
        top = top->next;
        delete (temp);
        --anzahl_elemente;
        return result;
    }
    

    Abgesehen von ersten Zeile, kann diese Funktion an 2 Stellen mit einer Exception fehlschlagen. An der ersten Stelle verbleibt das Element im Stack, bei der zweiten Stelle ist es bereits entfernt worden. Das ist nicht optimal, weil sich der benutzende Code nicht auf ein bestimmtes Verhalten einstellen kann.



  • camper schrieb:

    Den copy-ctor können wir eleganter schreiben, da alle notwendigen Operationen bereits in anderen Funktionen realisiert werden.

    template<class T>MyStack<T>::MyStack(const MyStack &other)
    :top(NULL), anzahl_elemente(0)
    {
        MyStack temp; // !!!
        for ( Element* p = other.top; p != NULL; p = p->next )
            temp.push( p->data );
        swap( temp );
    }
    

    sieht fast aus wie op= ? So ein Zufall 😉

    ne kann nicht funktionnieren, dann liegen die daten den verkehrten weg im Stack, darum muss man ja eine etwas längere funktion schriebn und nicht einfach eine pushmethode benutzen... Damit das funktionnieren könnte müsste man hinten anfangen und nach vorne fahren, klappt aber nicht mit nem stack...



  • Mit Linux wäre das nicht passiert.



  • hä was soll das denn heißen??

    naja egal, @camper, den code kann ich aber locker bei der Queue benutzen^^


  • Mod

    uhsuhz schrieb:

    camper schrieb:

    Den copy-ctor können wir eleganter schreiben, da alle notwendigen Operationen bereits in anderen Funktionen realisiert werden.

    template<class T>MyStack<T>::MyStack(const MyStack &other)
    :top(NULL), anzahl_elemente(0)
    {
        MyStack temp; // !!!
        for ( Element* p = other.top; p != NULL; p = p->next )
            temp.push( p->data );
        swap( temp );
    }
    

    sieht fast aus wie op= ? So ein Zufall 😉

    ne kann nicht funktionnieren, dann liegen die daten den verkehrten weg im Stack, darum muss man ja eine etwas längere funktion schriebn und nicht einfach eine pushmethode benutzen...

    stimmt wohl, hab ich nicht aufgepasst. Aber das try+catch brauchen wir wirklich nicht.

    template<class T>MyStack<T>::MyStack(const MyStack &other)
    :top(NULL), anzahl_elemente(other.anzahl_elemente)
    {
        MyStack temp;
        for ( Element *p = other.top, **q = &temp.top; p != NULL; p = p->next )
        {
            *q = new Element( p->data );
            q = &q->next;
        }
        std::swap( top, temp.top );
    }
    }
    


  • ich habs mal so gelassen, ich schau mir das später mal an...



  • camper schrieb:

    Bzgl. pop bin ich mir etwas unsicher:

    template<class T> T Stack<T>::pop()
    {
             if (! top) throw EmptyStackException();
             T result(top.data);
        Element* temp = top;
        top = top->next;
        delete (temp);
        --anzahl_elemente;
        return result;
    }
    

    Abgesehen von ersten Zeile, kann diese Funktion an 2 Stellen mit einer Exception fehlschlagen. An der ersten Stelle verbleibt das Element im Stack, bei der zweiten Stelle ist es bereits entfernt worden. Das ist nicht optimal, weil sich der benutzende Code nicht auf ein bestimmtes Verhalten einstellen kann.

    Hm, zwei Stellen? Ich nehem mal an, beim Copy-Ctor und beim return?
    Folgendes sollte dann aber einheitlich sein, so dass ein pop() auf jeden Fall das oberste Element entfernt:

    template<class T> T Stack<T>::pop()
    {
        if (! top) throw EmptyStackException();
        std::auto_ptr<Element> temp(top);
        top = top->next;
        --anzahl_elemente;
        return temp->data;
    }
    

Anmelden zum Antworten