In Elementfunktion eigene Klasse neu erzeugen
-
das funktioniert leider nicht
er versucht, aus nichtreservierten speicher zuzugreifen (laufzeitfehler).template <class datentyp> void Matrix<datentyp>::resize(const int iAnzZeilen, const int iAnzSpalten) { delete this; //hiermit funktioniert es und dies ist auch der code aus dem konstruktor: //a=new datentyp*[iAnzZeilen]; //for(int i=0;i<iAnzZeilen;i++) a[i]=new datentyp[iAnzSpalten]; //m=iAnzZeilen; //n=iAnzSpalten; *this = Matrix<datentyp>(iAnzZeilen, iAnzSpalten); //verursacht laufzeitfehler }in meiner matrixklasse ist a** das array mit den elementen und m,n die zeilen-/spaltenanzahl.
(bitte keine tipps, welche klassen ich verwenden kann, es geht hierbei eher ums lernen)
-
hermesasl schrieb:
das funktioniert leider nicht
er versucht, aus nichtreservierten speicher zuzugreifen (laufzeitfehler).delete this; ... *this = Matrix<datentyp>(iAnzZeilen, iAnzSpalten); //verursacht laufzeitfehler }Ist doch logisch: Du gibst vorher den Speicher der Klasse frei und dereferenzierst danach den (inzwischen ungültigen) this-Zeiger. Außerdem solltest du bei solchen Sachen immer aufpassen: Wenn die Klasse nun ganz normal auf dem Stack angelegt wurde und du delete aufrufst, krachts genau so.
-
mhh .. wie kann ich dann sonst den speicher reservieren und freigeben?
man kann ja dem zeiger this nichts zuweisen, alsothis = new Matrix<datentyp>(m,n);geht ja nicht.
-
hermesasl schrieb:
mhh .. wie kann ich dann sonst den speicher reservieren und freigeben?
man kann ja dem zeiger this nichts zuweisen, alsothis = new Matrix<datentyp>(m,n);geht ja nicht.Lösche einfach alles, was du im Konstruktor mit new angefordert hast und rufe danach den Konstruktor auf.
-
genau darum geht ja meine frage:
wie rufe ich den denn auf?void Matrix<datentyp>::resize(const int iAnzZeilen, const int iAnzSpalten) { ///genau das steht im Destruktor: for(int i=0;i<m;i++) delete[] a[i]; delete[] a; ///das steht im Konstruktor: //a=new datentyp*[iAnzZeilen]; //for(int i=0;i<iAnzZeilen;i++) a[i]=new datentyp[iAnzSpalten]; //m=iAnzZeilen; //n=iAnzSpalten; Matrix<datentyp>(iAnzZeilen, iAnzSpalten); //laufzeitfehler! }wenn ich nicht den konstruktor aufrufe, sondern den auskommentierten code, funktioniert es ja. aber ich möchte doch lieber den konstruktor verwenden

-
Wenn du den Konstruktor nicht selbst aufrufen kannst, dann verlagere doch deinen Code stattdessen in eine extra private Funktion __init () oder so und rufe diese Funktion dann im Konstruktor sowie in deiner resize () Funktion auf.
-
okay, dann mach ich das so ... hatte das auch schon im hinterkopf

danke für den tipp!
falls jemandem noch eine andere lösung einfällt, bin ich aber auch noch interessiert

-
in der elementfunktion
new (this) matrix<datentyp> (iAnzzeilen, iAnzspalten);aber was machst du, wenn eine exception auftritt?
dann sind nämlich die alten daten alle weg, obwohl sie das nicht sein müssten.
-
Du musst nur eine "swap" Funktion implementieren. Mit deren Hilfe kannst du dann operator = implementieren, und auch deine resize funktion:
void dings::swap(dings& other) { // in den meisten fällen musst du hier einfach nur alle member-variablen tauschen: std::swap(a, other.a); std::swap(m, other.m); std::swap(n, other.n); } dings& dings::operator = (dings const& other) { dings temp(other); // anderes dings kopieren swap(temp); // dieses dings mit kopie von anderem dings tauschen return *this; // fertig } void dings::resize(int newM, int newN) { dings temp(newM, newN); // neues dings erstellen // ggf. noch daten von "this" nach "temp" kopieren swap(temp); // dieses dings mit dem neuen dings tauschen }
-
das hört sich gut an und vereinfacht auch noch andere sachen - danke

-
renewer schrieb:
in der elementfunktion
new (this) matrix<datentyp> (iAnzzeilen, iAnzspalten);Wie gesagt eher schlecht, da du vorher evtl. das aktuelle Objekt freigeben musst (wenn es nicht auf dem Stack liegt - was du nicht so einfach feststellen kannst) und du dir dann noch für den Destruktor merken müsstes, wie das aktuelle Objekt erzeugt wurde (entweder vom Programmierer (Finger weg lassen) oder innerhalb des Klassen-Members (delete aufrufen)).