Wem langweilig ist oder eine Vektorklasse braucht
-
Wem langweilig ist oder eine neue Klasse für Vektoren ausprobieren möchte: Fände es nett, wenn ihr euch meldet, falls es Fehler gibt. Schaue sich an, wer möchte.
Mr. B
// ************************************************************************************************* // Datei: dynamicVector.h // // Zweck: Klasse, die Array-Verwaltung erleichtert // Hinweise: Bei einer Deklaration von 'dynamicVector Beispiel(5);' // hat der Vector die Elemente 0 bis einschließlich 5, // also 6 Elemente. // // Datum: 02.04.2005 (letzte Änderung) // Version: 2.0 // // Anmerkung: Ich hoffe, es hilft ein wenig! ;-) // ************************************************************************************************* template<class T> class dynamicVector { private: T *daten; int topIndex; unsigned long int vektorgroesse; static const int erhoehen_um = 10; public: dynamicVector(); // Array enthält Elemente 0 bis einschl. 10 dynamicVector(unsigned long int startgroesse); // Array enthält Elemente 0 bis einschl. startgroesse dynamicVector(unsigned long int startgroesse, T wert); dynamicVector(const dynamicVector &andererVector); // Copy-Konstruktor, übernimmt andere Objekte ~dynamicVector(); T& operator =(const dynamicVector &andererVector); T& operator [](unsigned long int position); void addTop(T wert); void setElementAt(unsigned long int position, T wert);// 'position' wird = 'topIndex'!!! void overwrite(unsigned long int position, T wert); // 'position' wird = 'topIndex', // wenn 'position' > 'topIndex' void fillTillTopIndexWith(T wert); void fillTillVectorgroesseWith(T wert); T getTop(); T getAt(unsigned long int position); bool isEmpty(); // Gibt TRUE, wenn Array leer ist int getTopIndex(); // Gibt 'topIndex' wieder int getVektorgroesse(); // Gibt 'vektorgroesse' wieder void coutTillTopIndex(); // Gibt Array bis 'topIndex' wieder void coutArrayFromTo(unsigned long int von, unsigned long int bis); void coutTillVektorgroesse(); // Gibt Array bis 'vektorgroesse' wieder void deleteTop(); void cutOut(unsigned long int position); void deleteAll(); // Array enthält Elemente 0 bis einschl. 10 void deleteAll(int neueStartgroesse); void setOberstenIndexAt(int position); void multiplySizeBy(float vielfaches); // Vergrößert Array um Vielfaches void growTo(unsigned long int neueGroesse); void sortIncreasingToEnd(); // Sortiert ansteigend zum Ende hin void sortFallingToEnd(); // Sortiert fallend zum Ende hin void swap(unsigned long int positionEins, unsigned long int positionZwei); void copyFromOnto(unsigned long int PositionVon, unsigned long int PositionAuf); }; // ================================================================================================= // KONSTRUKTOREN // ================================================================================================= template<class T> dynamicVector<T>::dynamicVector() { dynamicVector(10); } template<class T> dynamicVector<T>::dynamicVector(unsigned long int startgroesse) { vektorgroesse = startgroesse; daten = new T[(startgroesse + 1)]; topIndex = -1; } template<class T> dynamicVector<T>::dynamicVector(unsigned long int startgroesse, T wert) { dynamicVector(startgroesse); addTop(wert); } template<class T> dynamicVector<T>::dynamicVector(const dynamicVector &andererVector) { vektorgroesse = andererVector.vektorgroesse; topIndex = andererVector.topIndex; daten = new T[(vektorgroesse + 1)]; for(int i = 0; i <= topIndex; i++) daten[i] = andererVector.getAt(i); } template<class T> dynamicVector<T>::~dynamicVector() { delete [] daten; } // ================================================================================================= // OPERATOREN // ================================================================================================= template<class T> T& dynamicVector<T>::operator =(const dynamicVector &andererVector) { if(&andererVector!=this) { delete [] daten; vektorgroesse = andererVector.vektorgroesse; topIndex = andererVector.topIndex; daten = new T[(vektorgroesse + 1)]; for(int i = 0; i <= topIndex; i++) daten[i] = andererVector[i]; } return *this; } template<class T> T& dynamicVector<T>::operator [](unsigned long int position) { /*if(position > vektorgroesse) { std::cout << "\n\nFEHLER: Position ausserhalb des Vektors [operator [](unsigned long int position)]"; std::cout << "\nElement auf Vektorgroesse wird zurueckgegeben\n\n"; return daten[vektorgroesse]; }*/ if(position > vektorgroesse) { unsigned long int neueGroesse = position + erhoehen_um; growTo(neueGroesse); topIndex = position; } return daten[position]; } // ================================================================================================= // ADD // ================================================================================================= template<class T> void dynamicVector<T>::addTop(T wert) { topIndex++; if(topIndex > vektorgroesse) { unsigned long int neueGroesse = vektorgroesse + erhoehen_um; vektorgroesse = neueGroesse; T *temp = daten; daten = new T[(neueGroesse + 1)]; for(int i = 0; i < topIndex; i++) daten[i] = temp[i]; delete [] temp; } daten[topIndex] = wert; } template<class T> void dynamicVector<T>::setElementAt(unsigned long int position, T wert) { if(position > vektorgroesse) { unsigned long int neueGroesse = position + erhoehen_um; growTo(neueGroesse); } daten[position] = wert; topIndex = position; } template<class T> void dynamicVector<T>::overwrite(unsigned long int position, T wert) { if(position > topIndex) { if(position > vektorgroesse) { unsigned long int neueGroesse = position + erhoehen_um; growTo(neueGroesse); } topIndex = position; daten[position] = wert; } else daten[position] = wert; } template<class T> void dynamicVector<T>::fillTillTopIndexWith(T wert) { for(int i = 0; i <= topIndex; i++) daten[i] = wert; } template<class T> void dynamicVector<T>::fillTillVectorgroesseWith(T wert) { for(unsigned long int i = 0; i <= vektorgroesse; i++) daten[i] = wert; } // ================================================================================================= // GET // ================================================================================================= template<class T> T dynamicVector<T>::getTop() { return daten[topIndex]; } template<class T> T dynamicVector<T>::getAt(unsigned long int position) { if(position > vektorgroesse) { std::cout << "\n\nFEHLER: Position ausserhalb des Vektors [getAt(unsigned long int position)]"; std::cout << "\nElement auf Vektorgroesse wird zurueckgegeben\n\n"; return daten[vektorgroesse]; } else return daten[position]; } template<class T> bool dynamicVector<T>::isEmpty() { return topIndex == -1; } template<class T> int dynamicVector<T>::getTopIndex() { return topIndex; } template<class T> int dynamicVector<T>::getVektorgroesse() { return vektorgroesse; } template<class T> void dynamicVector<T>::coutTillTopIndex() { std::cout << endl << endl; for(int i = 0; i <= topIndex; i++) std::cout << i << ".Element:\t" << getAt(i) << endl; std::cout << endl << endl; } template<class T> void dynamicVector<T>::coutArrayFromTo(unsigned long int von, unsigned long int bis) { if(von <= vektorgroesse && bis <= vektorgroesse) { std::cout << endl << endl; for(von; von <= bis; von++) std::cout << von << ".Element:\t" << getAt(von) << endl; std::cout << endl << endl; } else { std::cout << "\n\nFEHLER: Position(en) ausserhalb des Vektors" std::cout << "\n[coutArrayFromTo(unsigned long int von, unsigned long int bis)]\n\n"; } } template<class T> void dynamicVector<T>::coutTillVektorgroesse() { std::cout << endl << endl; for(unsigned long int i = 0; i <= vektorgroesse; i++) std::cout << i << ".Element:\t" << getAt(i) << endl; std::cout << endl << endl; } // ================================================================================================= // DELETE // ================================================================================================= template<class T> void dynamicVector<T>::deleteTop() { if(topIndex > -1) topIndex--; } template<class T> void dynamicVector<T>::cutOut(unsigned long int position) { if (position <= vektorgroesse) { int *temp = new T[topIndex]; for(unsigned long int i = 0; i < position; i++) temp[i] = daten[i]; for(i = position + 1; i <= topIndex; i++) temp[i-1] = daten[i]; topIndex--; delete [] daten; vektorgroesse = topIndex + erhoehen_um; daten = new T[(vektorgroesse + 1)]; for(i = 0; i <= topIndex; i++) daten[i] = temp[i]; delete [] temp; } else std::cout << "\n\nFEHLER: Position ausserhalb des Vektors [cutOut(unsigned long int position)]\n\n"; } template<class T> void dynamicVector<T>::deleteAll() { delete [] daten; vektorgroesse = erhoehen_um; daten = new T[(vektorgroesse + 1)]; topIndex = -1; } template<class T> void dynamicVector<T>::deleteAll(int neueStartgroesse) { delete [] daten; vektorgroesse = neueStartgroesse; daten = new T[(neueStartgroesse + 1)]; topIndex = -1; } // ================================================================================================= // EXTRAS // ================================================================================================= template<class T> void dynamicVector<T>::setOberstenIndexAt(int position) { if(position <= vektorgroesse && position > -2) topIndex = position; else if(position > vektorgroesse) { unsigned long int neueGroesse = position + erhoehen_um; growTo(neueGroesse); topIndex = position; } else std::cout << "\n\nFEHLER: Position kleiner als -1 [setOberstenIndexAt(int position)]\n\n"; } template<class T> void dynamicVector<T>::multiplySizeBy(float vielfaches) { if(vielfaches > 1) { unsigned long int neueGroesse = vektorgroesse * vielfaches; vektorgroesse = neueGroesse; T *temp = new T[(vektorgroesse + 1)]; for(int i = 0; i <= topIndex; i++) temp[i] = daten[i]; delete [] daten; daten = new T[(neueGroesse + 1)]; for(i = 0; i <= topIndex; i++) daten[i] = temp[i]; delete [] temp; } else { std::cout << "\n\nFEHLER: Array wuerde verkleinert oder bliebe gleich gross, aber wuerde nicht vergroessert"; std::cout << "\nVielfaches muss groesser sein als 1. [multiplySizeBy(float vielfaches)]\n\n"; } } template<class T> void dynamicVector<T>::growTo(unsigned long int neueGroesse) { if(neueGroesse > vektorgroesse) { vektorgroesse = neueGroesse; T *temp = new T[(vektorgroesse + 1)]; for(int i = 0; i <= topIndex; i++) temp[i] = daten[i]; delete [] daten; daten = new T[(neueGroesse + 1)]; for(i = 0; i <= topIndex; i++) daten[i] = temp[i]; delete [] temp; } else { std::cout << "\n\nFEHLER: Array wuerde verkleinert, nicht vergroessert"; std::cout << "\njetzige Groesse: " << vektorgroesse << " gewuenschte Groesse: " << neueGroesse; std::cout << "\n[growTo(unsigned long int neueGroesse)]\n\n"; } } template<class T> void dynamicVector<T>::sortIncreasingToEnd() { for(int arrayAnfang = 0; arrayAnfang < topIndex; ++arrayAnfang) { int minPos = arrayAnfang; int minWert = daten[arrayAnfang]; for(int suchPos = arrayAnfang + 1; suchPos <= topIndex; ++suchPos) { if(daten[suchPos] < daten[minPos]) { minPos=suchPos; minWert=daten[suchPos]; } } swap(&daten[arrayAnfang],&daten[minPos]); } } template<class T> void dynamicVector<T>::sortFallingToEnd() { for(int arrayAnfang = 0; arrayAnfang < topIndex; ++arrayAnfang) { int maxPos = arrayAnfang; int maxWert = daten[arrayAnfang]; for(int suchPos = arrayAnfang + 1; suchPos <= topIndex; ++suchPos) { if(daten[suchPos] > daten[maxPos]) { maxPos = suchPos; maxWert = daten[suchPos]; } } swap(&daten[arrayAnfang], &daten[maxPos]); } } template<class T> void dynamicVector<T>::swap(unsigned long int positionEins, unsigned long int positionZwei) { unsigned long int groesser; if (positionEins > positionZwei) // Größeren herausfinden groesser = positionEins; else if (positionZwei > positionEins) groesser = positionZwei; else std::cout << "\n\nFEHLER: Positionen sind gleich\n[swap(unsigned long int positionEins, unsigned long int positionZwei)]\n\n"; if (positionEins != positionZwei && groesser > vektorgroesse) // Wenn groesser > Vektor, dann muss { // Vektor vergrößert werden unsigned long int neueGroesse = groesser + erhoehen_um; growTo(neueGroesse); topIndex = groesser; } if (positionEins != positionZwei && groesser < vektorgroesse) // Tausch nur wenn Positionen nicht identisch { T temp = daten[positionEins]; daten[positionEins] = daten[positionZwei]; daten[positionZwei] = temp; } } template<class T> void dynamicVector<T>::copyFromOnto(unsigned long int PositionVon, unsigned long int PositionAuf) { unsigned long int groesser; if (PositionVon > PositionAuf) // Größeren herausfinden groesser = PositionVon; else if (PositionAuf > PositionVon) groesser = PositionAuf; else std::cout << "\n\nHINWEIS: Positionen sind gleich\n[copyFromOnto(unsigned long int PositionVon, unsigned long int PositionAuf)]\n\n"; if (PositionVon != PositionAuf && groesser > vektorgroesse) // Wenn groesser > Vektor, dann muss { // Vektor vergrößert werden unsigned long int neueGroesse = groesser + erhoehen_um; growTo(neueGroesse); topIndex = groesser; } if (PositionVon != PositionAuf && groesser < vektorgroesse) // Kopie nur wenn Positionen nicht identisch { daten[PositionAuf] = daten[PositionVon]; } }
-
In so einer Low-Level-Klasse ausgaben über cout zu machen ist einfach nur scheisse. Benutz Exceptions oder assert.
-
Ja, cout ist schlecht. Damit fällt es für alle nicht-Konsolenprogramme flach. Außerdem solltest du für Indizes und Größen size_t verwenden. Iteratoren fehlen auch. Dass er dagegen nicht STL-konform ist (was auch einige gleich bemerken werden) ist deine Design-Entscheidung.
-
Außerdem solltest du englisch und deutsch nicht mischen.
-
static const int erhoehen_um = 10;Lame. Lame. Lame. Lame. Lame.
-
Optimizer schrieb:
Ja, cout ist schlecht.
Bin ja auch nur "Hobbyprogrammierer", der in den Ferien zu billigen Programmen kommt und nicht dazu kommt, mal ENDLICH Volkards Kurs zu beenden.
Damit fällt es für alle nicht-Konsolenprogramme flach.
Ich programmierte bisher nur für die Konsole.
Außerdem solltest du für Indizes und Größen size_t verwenden.Iteratoren fehlen auch.
Da ich nich viel Zeit habe, mir DAS anzueignen, weiß ich nicht mals, was das ist.
Mr. B
-
Hab mir jetzt nicht alles angeschaut, sondern nur mal kurz überflogen, 2 Sachen zu den bisherigen Anmerkungen sind mir trotzdem noch aufgefallen.
1. Wenn du nicht auf das bewährte swap Verfahren beim Instanz Kopieren zurückgreifen willst, dann achte zumindest darauf, zuerst neuen Speicher anzufordern und dann alten freizugeben. Ansonsten gehen deine Objekte uU "kaputt" und du erzeugst damit undefiniertes Verhalten.
2. Achte auf const-correctness! Kann man eigentlich nie oft genug wiederholen.