PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frage an die C++ Stil-Experten


Senior Sanchez
2010-09-16, 14:32:24
Hi,

Also ich programmiere nun seit langer Zeit mal wieder etwas mehr C++ und angesichts der Frage kann ich schon gleich sagen, dass ich eigentlich aus der garbage collected Welt stamme.

Folgendes Problem:
Ein Objekt einer Klasse hat eine map als Attribut. Ich möchte jetzt gerne eine Methode schreiben, die alle Values dieser map als Vector oder List zurückgibt. Das zu realisieren ist für mich kein Problem, aber mir gehts da um den Stil des Speichermanagements. Generell gilt ja die Regel, dass wer den Speicher erzeugt, ihn auch wieder freigeben soll.

Damit ergibt sich folgende 1. Idee: Wenn ich den Vector/List in der Methode erzeuge, muss es auf dem Heap landen. Wenn ich jetzt aber einfach einen Zeiger auf diesen Vector/List per Methode zurückgebe, weiß ich nicht, wann ich den Speicher wieder freigeben muss. Das könnte natürlich der Aufrufende meinem Objekt später signalisieren, aber das finde ich irgendwie unschön.

Die zweite Variante entspricht mehr dem Stil den ich aus der embedded Entwicklung bei fehlendem Heap kenne. Der Aufrufende reicht einen Zeiger auf eine Vector/List per Argument an die Methode, die dann diesen Container mit entsprechenden Kopien der map Values befüllt. Der Aufrufende kümmert sich dann später auch um das Freigeben des Speichers. Ist diese Variante gebräuchlich?

Die dritte Variante ist die Nutzung von smart pointers und da ich auch boost benutze, hätte ich sie sowieso da. Aber macht das an der Stelle Sinn oder ist das mit Kanonen auf Spatzen geschossen?

Vielen Dank schon mal!

Trap
2010-09-16, 14:42:08
Eine 4. Variante wäre das Objekt per Wert zurückzugeben. Hat die einfachste Semantik, ist höchstens 100% Overhead, da du fürs Erzeugen der Liste sowieso alles einmal kopieren musst, und eventuell gibt es den Overhead nicht, wenn man NRVO hat.

Senior Sanchez
2010-09-16, 14:43:45
Eine 4. Variante wäre das Objekt per Wert zurückzugeben. Hat die einfachste Semantik, ist höchstens 100% Overhead, da du fürs Erzeugen der Liste sowieso alles einmal kopieren musst, und eventuell gibt es den Overhead nicht, wenn man NRVO hat.

Klingt auch nach ner guter Idee!
Was heißt NRVO?

Trap
2010-09-16, 14:45:16
named return value optimization: http://msdn.microsoft.com/en-us/library/ms364057(VS.80).aspx

Senior Sanchez
2010-09-16, 14:47:26
Ah, danke, ich les mal rein.

Der GCC 4.2 kann das bestimmt, oder? ;)

Trap
2010-09-16, 15:01:22
Klar. Die Frage ist nur in welchen Fällen, oft gibt es Einschränkungen wann der Compiler die Optimierung anwenden kann. Bei Exceptions oder mehreren returns gehts oft nicht.

Senior Sanchez
2010-09-16, 15:02:58
Jupp, habe ich auch gelesen, aber für meinen Fall sollte es gehen. Es gibt nur ein return, keine Exception und sollte NRVO funktionieren und nicht nur RVO, dann passt das. :)

Nighthawk13
2010-09-16, 16:59:49
Smart Pointer sind durchaus ne Option hier. Evtl. auch einfach ein const_iterator auf map.begin()/end().

Ob man eine Kopie oder ein Pointer zurückgibt, macht ja auch einen logischen Unterschied(Will man die Daten in der Map verändern können? Greifen später evtl. mehrere Threads darauf zu und man braucht eine unabhängige Kopie? usw.)

Senior Sanchez
2010-09-16, 17:52:02
Smart Pointer sind durchaus ne Option hier. Evtl. auch einfach ein const_iterator auf map.begin()/end().

Ob man eine Kopie oder ein Pointer zurückgibt, macht ja auch einen logischen Unterschied(Will man die Daten in der Map verändern können? Greifen später evtl. mehrere Threads darauf zu und man braucht eine unabhängige Kopie? usw.)

Einen const_iterator zurückzugeben geht theoretisch, ist aber nicht so schön, finde ich. Denn als Values verwende ich in der Map Vektoren und diese Funktion, die alle Werte zurückgeben soll, sodazu diese Vektoren in einem einzigen vereinen. Gebe ich einen const_iterator zurück habe ich dagegen eine zusätzliche Stufe der Indirektion beim Aufrufer und das will ich vermeiden.

Also verändert wird da nichts, da wird nur gelesen.

Senior Sanchez
2010-09-22, 21:27:28
So, Problem ist gelöst. Ich habe Traps Variante genutzt und das funktioniert soweit erstmal sehr gut.

Mal eine andere Frage: Ab welchem Punkt würdet ihr den Einsatz von Smartpointers empfehlen? Macht das immer Sinn oder nur vereinzelt? Wenn zweiteres, sind dann in einer Applikation Mischformen von Standard-Pointers und Smartpointers zu empfehlen?

Trap
2010-09-22, 23:42:03
Smartpointer haben hauptsächlich 2 Nachteile:
a) sie sind langsamer
b) sie können bei Graphen von Objekten Memoryleaks erzeugen

Wenn man sie einfach nur als Handle auf Daten ohne Verweise auf andere Objekte benutzt machen sie höchstwahrscheinlich keine Probleme.

Sobald die Objekte im Smartpointer weitere Smartpointer enthalten muss man aufpassen.