Memory leak bei überladenen Operatoren verhindern
-
Hallo alle zusammen,
ich will mal einige numerische Verfahren implementieren und bin dabei auf eine Frage gestoßen. Meine Klassendefinition sieht so aus:
class Matrix { [...] Matrix& operator=(const Matrix& original); Matrix& operator+(const Matrix& summand); [...] int m_rows, m_cols; }; [...] Matrix& Matrix::operator+(const Matrix& original) { Matrix* tmp = new Matrix(m_rows, m_cols); [...] return *tmp; }Das Problem ergibt sich dann, wenn ich sowas schreibe wie:
Matrix a,b,c; c = a + b;Dann erzeugt a + b ja eine neue Instanz von Matrix, die nach der Zuweisung als verwaistes Objekt im Speicher liegt. (Wie) Kann man sowas elegant umgehen?
Gruß Andreas
-
Kommst du zufällig von Java?
In C++ müssen Objekte nämlich nicht mit new angelegt werden.
Du kannst auch einfach schreiben:
Matrix& Matrix::operator+(const Matrix& original) { Matrix tmp(m_rows, m_cols); [...] return tmp; }Auf Member wird dann per . anstatt -> zugegriffen.
Ps:
Außerdem solltest du keine Referenz zurückgeben, da die sonst auf ein gelöschtes Objekt zeigt, da der Scope der Funktion verlassen wurde.
-
Nicht Matrix& zurückgeben, sondern einfach Matrix.
Copy- Constructor und Assignment- Operator muss implementiert sein.Edit: Nimm Dir doch als Bsp. std::complex<T>
-
Ja, ich komme tatsächlich von Java und habe noch nicht viel Erfahrung mit c++, aber bei solchen Projekten ist dann Operatorüberladung einfach deutlich von Vorteilen.
Bei der Methode mit den Copy-Konstruktoren würde dann doch beia = b + c * d;z.B für c * d und für b + c * d je eine Instanz erzeugt werden. Endet dann deren Scope am Ende der Zeile?
Gruß Andreas
PS: Danke für eure schnellen Antworten.
-
gurumusch schrieb:
[...]Endet dann deren Scope am Ende der Zeile?
Der Scope liegt zwischen den geschwungenen Klammern:
{ obj a; { obj b; }//b wird zerstört }//a wird zerstört
-
c++ besitzt tatsächlich harte scopes. im gegensatz zu java werden lokale objekte (ohne new erzeugt) sofort bei verlassen ihres scopes zerstört.
-
Danke für eure Hilfe. Also, jetzt sieht es dann so aus:
class Matrix { [...] Matrix(const Matrix& original) Matrix operator=(const Matrix& original); Matrix operator+(const Matrix& summand); [...] int m_rows, m_cols; }; [...]Ich schätze, ich werde werde c++ an der Stelle auch etwas besser verstehen, wenn ich es erstmal 2-3 mal debuggt habe.
Gruß Andreas
-
Um die temporären Variablen und ihr Verhalten zu beobachten und verstehen könntest du im Kontruktor und Destruktor ein kurzes cout-statement einbauen - dann siehst du auch wie der Kompiler die temporären Objekte eventuell wegoptimiert..
-
Beim Assignement Operator sollte eine Referenz zurückgegeben werden.
(Sorry, dass ich das nicht schon oben geschrieben habe.)// Dekl. Matrix& operator=(const Matrix& original); // Impl. Matrix& Matrix::operator=(const Matrix& original) { // // kopieren der Member... // return *this; }Bei den Überladungen +, -, *, / sollten Kopien zurückgegeben werden.