Fragen zu new/delete und operator<<
-
Erstmal skizziere ich die Klassen, die ich habe:
class Punkt{ public: /*Daten*/ short x,y; /*Konstruktoren*/ Punkt(); Punkt(short xpos,short ypos); /*Funktionen*/ bool operator==(Punkt Vergleich); Punkt operator-(); Punkt operator+(Punkt Summand); /*usw. usf. ...*/ };So, mit dieser Klasse sollen also Punktobjekte erzeugt werden können, mit denen gerechnet können werden soll.
Jetzt kommt die eigentliche Problemklasse, die im wesentlichen eine 'Menge von Punkten' verpacken können soll, und mit der dann auch Mengenoperationen möglich sein sollen (Schnittmenge etc.)
class Punktmenge{ /*Daten*/ Punkt* P; /*Hieraus soll ein dynamisch wachsendes Array aus Punktobjekten entstehen können */ unsigned short anzahl; /* Mit dieser Variable soll Buch darüber geführt werden, wieviele Punkte momentan im Array P stecken*/ /* Konstruktoren*/ public: Punktmenge():P(NULL),anzahl(0){} /* Und jetzt möchte ich den operator<< dergestalt überladen, dass damit Punktobjekte in die Punktmenge eingefügt werden können */ bool operator<<(Punkt Einschub){ if(!P){ // Fallunterscheidung ob P gleich NULL ist P=new Punkt[(anzahl+1)]; if(P){ P[0]=Einschub; anzahl=1; return true; } else return false; } else if(P){ // oder nicht Punkt* helper=new Punkt[(anzahl+1)]; if(helper){ for(int i=0;i<anzahl;i++) helper[i]=P[i]; helper[anzahl]=Einschub; anzahl++; delete[] P; P=helper; return true; } else return false; } return false; } /* Ende der Funktion operator<< */ /* Restliche Funktionsdeklarationen der Klasse Punktmenge */ };Eigentlich arbeitet die Funktion operator<< so, wie ich es mir erhofft hatte,
um in anderen Programmteilen also Anweisungen wiePunktmenge M; M << Punkt(3,5);schreiben zu können.
Ich habe aber gehört, dass Speicherallokationen ziemlich zeitaufwändig sind, und deshalb im Falle, dass beispielsweise mit einer Schleife wie
Punktmenge M; for(int i=0;i<=1000;i+=100) for(int j=0;j<=1000;j++) M << Punkt(i,j); /* Um die Sinnhaftigkeit dieser Schleife geht es nicht */immerhin 10.000 derartige Allokationsanweisungen ausgeführt werden müssten (aufgrund des Operators <<)
Was könnte man unternehmen, um in solchen Fällen nicht 10.000 Allokationsanweisungen zu benötigen? Ist es vernünftiger, zuerst einmal eine 'vermutlich benötigte' Speichermenge zu allokieren, und dann mittels des Operators << einfach die Punkte nur noch in die Punktmenge hineinzuschreiben - ohne Allokationsanweisungen? Dann kann doch immer noch das Problem auftreten, dass der 'vermutlich benötigte' Speicherbereich trotzdem nicht ausreicht, und man würde womöglich in einen nicht-allokierten Speicherbereich hineinschreiben?
Jedenfalls vorweg einmal danke für Denkanstöße, wie man das Problem außerdem noch angehen könnte.
-
Die beste Lösung wäre es wohl, daß du anstelle der nackten Zeiger einen STL-Container verwendest (z.B. vector<>) - da brauchst du dich nicht mehr um den Speicher zu kümmern (und die STL-Container sind auch so gebaut, daß sie recht vernünftige Laufzeiten liefern).
-
Eigentlich möchte ich gerne den Umgang mit Zeigern und überladenen Operatoren trainieren, mir ist schon klar, dass es vermutlich vorgefertigte Lösungen gibt.
Was ich gerne eines Tages schreiben können will sind solche Anweisungen:
Punktmenge A,B; (A && B).out(); /* Ausgabefunktion fuer die Schnittmenge */Derartige Anweisungen sind mit <vector> Objekten gar nicht möglich.
Es soll also eine Art 'Trainingsübung' sein.
Und natürlich soll auch nicht ein und derselbe Punkt plötzlich doppelt im gleichen Container stecken (das wäre ja unsinnig wenn zwei Exemplare von (1/1) in ein der selben Punktmenge stecken würden).
Mit hoher Wahrscheinlichkeit soll die Punktmengenklasse auch noch als Basisklasse für speziellere Punktmengen zu gebrauchen sein. Mit <vector> klappt das doch auch nicht?
Sorry wenn die Fragen naiv klingen sollten, aber ich bin nicht gerade ein C++ Profi, sondern ziemlicher Anfänger!
-
Erstmal ging es nicht darum, anstelle der "Punktmenge" auf vector zu setzen - sondern zur Datenspeicherung IN deiner Klasse einen vector zu verwenden.
Und im Zweifelsfall kannst du dich bei deiner Speicherverwaltung auch an einem vector orientieren - der speichert zusätzlich zur aktuellen Größe auch eine Kapazität (die gibt an, wieviel Speicher er tatsächlich verwendet) und verdoppelt seinen Speicher, wenn die Kapazität überschritten wird - auf die Weise wird er zwar auch gelegentlich seinen Inhalt umkopieren müssen, aber nicht bei jeder push_back()-Anweisung.