ERLEDIGT
NEIN
NEIN
ANTWORTEN
11
11
ZUGRIFFE
247
247
EMPFEHLEN
-
Hallo

Hat man eine selbstdefinierte Klasse A und man möchte eine Funktion schreiben, die ein Objekt dieser Klasse zurückgibt, wie geht man am Besten vor?
Ich habe drei Alternativen im Angebot:
Wobei ich mir hier unsicher bin, ob der so erstellte Zeiger auf das Objekt vom Typ A innerhalb der Methode nach dem Methodenauffruf nicht ungültig wird ?Code :1 2 3 4 5
A* methodeXY() { // Berechnungen A* a = new A(...); return a; }
Hier wird eine Kopie erstellt, was die Laufzeit drückt.Code :1 2 3 4
A methodeXY() { // Berechnungen A* a = new A(...); return *a;
Auch hier die Frage, ob der Zeiger nach dem Methodenaufruf noch gültig ist?Code :1 2 3 4
void methodeXY(A* a) { // Berechnungen a = new A(...); }
Welche Variante ist die eleganteste ? Welche sollte man vorziehen und welche meiden ?
Danke und schöne Grüße, Cyraid
EDIT: Syntaktische Fehler ausgebessert.Geändert von Cyraid (15.05.10 um 15:16 Uhr)
-
Wenn du das Objekt selbst zurückgeben willst, warum benutzt du nicht einfach
return *this;
?
Gruß,
badday
-
-
Hallo Cyraid!
Deine zweite Variante ist syntaktisch nicht korrekt, denn new liefert dir einen Zeiger zurück und kann daher nicht direkt nach A umgewandelt werden.
Deine dritte Variante funktioniert nicht, denn du musst bedenken, dass es sich bei deinem Funktionsargument nur um eine Variable mit dem gleichen Inhalt handelt wie du sie später aufrufst. Daher hat eine Wertzuweisung an dieses lokale Objekt keinen Einfluss auf das Objekt, mit dem du die Funktion aufrufst.
Der Speicher, den du mit new allozierst ist bekanntermassen persistent bis zu einem Aufruf an delete oder dem Programmende.
Für deine dritte Variante gäbe es die Möglichkeit folgendes zu verwenden:
Code :1 2 3 4 5 6
void CreateInstance(A** ppDest) { if(ppDest == NULL) // errorhandling (exception werfen, ...) *ppDest = new A; }
Ich finde das allerdings problematisch, da man blind davon ausgeht, dass das worauf ppDest zeigt ein korrekter Platz ist.
/Edit:
Meine Nummerierungen decken sich leider nicht mit deinen Codesnippets, aber es sollte dennoch klar sein, was gemeint ist
Geändert von Cromon (15.05.10 um 15:18 Uhr)
-
Ich würde hier einfach einen Smart-Pointer mit Verwendungszähler verwenden.
Wenn du im 1. Versuch das Objekt völlig neu erstellst, kann du das ihne Probleme so machen (soweit ich das sehe), allerdings musst du halt später delete aufrufen.
Gruß,
badday
-
Bei Code 3, das "*A a" soll wohl "A *a" heißen?
Bei Variante 1 bleibt der Pointer gültig, ist soweit ok.
Bei Variante 3 reservierst du Speicher, auf den du nie wieder zugreifen kannst und verstopfst damit nur den Speicher; also weg damit.
Bei Allokierungen in Methoden vergisst man aber leicht aufs freigeben danach.
Besser da freigeben, wo es auch reserviert wird.
-
@Cromon: Danke für deine ausführliche Antwort.

Entschuldigung, da haben sich beim schnellen Abtippen ein paar syntaktische Fehler eingeschlichen. Habe sie korrigiert.
Die ausgebesserte 2.Variante wäre also eine gute Art der Realisierung trotz des Kopierens ?
Stimmt, danke für den Hinweis. Das bedeutet demnach, dass die 1. Variante problemlos funktionieren würde. Gibt es für 1. Variante Nachteile? Ist das ein guter Stil?
Schöne Grüße, Cyraid
-
Nein, die zweite Variante ist sehr schlecht. Der Speicher, den du da allozierst mit new kannst du nie mehr freigeben, da du die Adresse nicht zurückgibst.
Zum Thema kopieren:
Praktisch alle Optimierer optimieren solche Sachen, dass das dennoch über Zeigerrückgabe realisiert wird und der Kopiervorgang unterdrückt wird. Schau dir dazu einfach mal den Assemblercode an, den dein Compiler generiert (am besten zur Laufzeit via Debugger und einem Breakpoint).
-
Stimmt.
Danke für die Informationen. Demnach ist also eine Variante mit Kopie in Ordnung? Beispielhaft zwei Versionen:
Code :1 2 3 4 5
A methodeXY() { // Berechnungen A a(...); return a; }
oder
Code :1 2 3 4 5
void methodeXY(A* a) { // Berechnungen A b(...); *a = b; }
Gibt es zwischen diesen beiden Nachteile/Vorteile ?
Schöne Grüße, Cyraid
-
Warum benutzt du bei deiner zweiten Methode nicht einfach eine Referenz?
Gruß,
badday
-
Dass Kopieren generell in Ordnung ist kann man so nicht sagen. Der Optimierer hat auch irgendwo seine Grenzen und fixen Möglichkeiten. Es sollte nur sagen, dass praktisch alles immer mit Bedacht ausgedrückt werden sollte, im Sinne von "sag niemals nie".
Wenn du unnötige Kopien vermeiden kannst spricht eigentlich nichts dagegen das auch zu tun ausser du weisst zu 100%, dass dein Optimierer sich genau diese Gedanken auch macht und dann deinen Code entsprechend umformt.
-
Finde ich je nach Methode auch eine gute Idee.
Code cpp:1 2 3 4
void machWas( A& a ) { a.machwas(); a.machNochWas(); }
Dann kannst du machen:
Code cpp:1 2
A a; machWas(a);
Macht natürlich nur Sinn, wenn "machWas" nicht als Methode von A besser aufgehoben wäre.
Weniger Sinn macht das natürlich, wenn du ein Objekt erzeugen möchtest. Aber je nach Verwendung würd ich wahlweise einfach das Objekt zurück geben (und hoffen dass der Compiler optimiert) oder einen auto_ptr oder shared_ptr zurück geben. C++0x bringt dann irgendwie Movable-Dinger oder so, womit man so eine Rückgabe ohne kopie machen kann.
Ähnliche Themen
-
Wurf eines Objekts
Von Cromon im Forum Coders TalkAntworten: 9Letzter Beitrag: 22.04.10, 19:44 -
Referenznummer eines Objekts
Von greggy80 im Forum Javascript & AjaxAntworten: 4Letzter Beitrag: 16.09.09, 16:31 -
Nachbelichten eines Ai-Objekts
Von jassebutter im Forum Vektor-ProgrammeAntworten: 7Letzter Beitrag: 20.08.09, 14:23 -
Rekonvertierung eines Objekts möglich?
Von pixels pix im Forum Cinema 4DAntworten: 3Letzter Beitrag: 07.06.07, 22:04 -
OOP-Zeitpunkt der Initialisierung eines Objekts
Von TomHH im Forum PHPAntworten: 0Letzter Beitrag: 28.12.04, 16:32





Zitieren

Login






