Stack Klasse
-
Habe mir eine dynamische Stack-Klasse geschrieben.
Kann man das eleganter lösen (ohne kopieren mit memcpy) ?template <class T> class Stack { private: int le; T *sta,*copy; void cp(int add){ copy=new T[le]; memcpy(copy,sta,le*sizeof(T)); delete sta; le+=add; sta=new T[le]; memcpy(sta,copy,(le-add)*sizeof(T)); delete copy;} public: Stack(){le=0;sta=new T[0];} ~Stack(){delete sta;} rein (T in) { cp(1); sta[le-1]=in; } T raus() { if(le) { T te=sta[--le]; cp(0); return te; } else return NULL; } bool beof() {return !le;} };
-
ich frag mich immer warum leute die räder neu erfinden wenn man schon voll optimierte möglichkeiten hat ..
-
Da ich Neuling in C++ bin ist sowas eine gute Übung.
Finde ich jedenfalls...
-
Wenn Du elemente von Stack nimmst, solltest Du sie auch löschen.
(beim nächsten mal den Quelltext bitte etwas leserlicher)
-
void cp(int add){ copy=new T[le]; memcpy(copy,sta,le*sizeof(T)); delete sta; le+=add; sta=new T[le]; memcpy(sta,copy,(le-add)*sizeof(T)); delete copy;}
mit add übergebe ich ob der Stack wachsen soll bzw nicht.
Mit der Methode raus wird die Größe des Stacks decrementiert.
[/cpp]
T raus()
{
if(le)
{
T te=sta[--le];
cp(0);
return te;
}
}
[cpp]
-
Ja, bei add holst du Dir speicher mit new, den Du aber auch wieder freigeben solltest, wenn er nicht mehr benötigt wird.
-
void cp(int add){ copy=new T[le]; memcpy(copy,sta,le*sizeof(T)); delete sta; le+=add; sta=new T[le]; memcpy(sta,copy,(le-add)*sizeof(T)); delete copy;}
T raus() { if(le) { //Hier wird die größe des Stacks verkleinert T te=sta[--le]; //In cp wird nun durch Übergabe von 0 und durch die decrementierung //von le der Stack kleiner cp(0); return te; } else return NULL; }
-
Ok, du machst das sorum.
Warum baust Du den Stack nicht aus einer einfach verketteten Liste?
struct node { int wert; node *prev; };
Wären dann z.B. die Stackelemente.
class my_stack { private: int laenge; ..... public: bool push(int i); bool pop(int i); int size(); };
!!!!!!!!!ist nicht vollständig
-
Ich habe mehrere Kritikpunkte, zuerst ernsterer Natur:
- die Funktion rein hat keinen Rückgabetyp. Meines Wissens ist implizit-int in C++ nicht erlaubt. Wie wärs mit void?
- Wenn du ein Array mit new anforderst, musst du es mit delete[] wieder freigeben. (das betrifft alle 3 Vorkommen von delete bei dir)
- mit memcpy kannst du nur POD-Typen (plain old data) kopieren, d.h. im wesentlichen primitive Datentypen und structs aus primitiven Datentypen. Klassen mit Konstruktoren usw. können nicht sicher mit memcpy kopiert werden, da memcpy einfach den Speicher kopiert und nicht den Kopierkonstruktor bzw. Zuweisungsoperator aufruft. Entweder von Hand kopieren, oder den copy-Algorithmus oder den unintialized_copy-Algorithmus, je nachdem.
Stilsachen:
- ungünstige Formatierung. Ich musste deinen Quältext erst in einen Editor pasten und umformatieren
- unverständliche Namensgebung
2a) btw die Stack-Operationen heißen normalerweise push und pop. beof assoziiert mit end of file, nenn die lieber empty. - komische Rückgabe wenn bei raus der Stack leer ist. Zum einen kann es sein, dass es Typ nicht implizit aus 0 konstruiert werden kann, zum anderen ist 0 ein ganz normaler Wert, den man vorher mit rein() auf den Stack gepackt haben könnte. Hier bieten sich Exceptions an.
- bei jedem rein-Aufruf alles umzukopieren ist extrem verschwenderisch mit der Rechenzeit. Es bietet sich an, bei einer notwendigen Vergrößerung gleich etwas mehr zu allozieren, beispielsweise die Größe zu verdoppeln, und dann den ungenutzten Platz aufzufüllen, bis eine neue Vergrößerung ansteht.
- alles 2mal umzukopieren ist ebenfalls nicht sehr elegant. Es würde doch reichen, wenn du neuen Platz anforderst, dann die Objekte kopierst, dann delete[] sta, und dann sta = das eben allozierte.
Zur Exceptionsicherheit sag ich jetzt mal nix. Wenn dich das interessiert, nimm mal Exceptional C++ zur Hand. Da wird in einem Kapitel das Design einer Stack-Klasse im Detail mit besonderem Augenmerk auf Exceptionsicherheit durchexerziert.