Referenz als Rückgabewert
-
Bashar schrieb:
CString cstr2; cstr2.swap(cstr1.ToUpper());
und jetzt erklär noch mal den unterschied zu
CString cstr2; cstr2.operator=(cstr1.ToUpper());
holla. steh ich auf der leitung?
-
DrGreenthumb schrieb:
Hm, heißt das nrvo funktioniert nur bei Initialisierungen?
Bei NRVO wird intern der Funktion ein Zeiger auf das Zielobjekt übergeben und das zurückgegebene Objekt direkt dort konstruiert. Bei Initialisierung klappt das wunderbar, aber bei Zuweisung nicht mehr: Der Zuweisungsoperator ist schließlich was anderes als der Kopierkonstruktor.
Also wird erstmal ein temporäres Objekt erzeugt, auf welches dem Zuweisungsoperator eine Referenz übergeben wird. Da innendrin wird dann nochmal kopiert (wenn wir copy-on-write mal ausschließen)Da kommt jetzt davie's Einwand ins Spiel: Mit swap wird eben nicht kopiert. Die alte leere Hülle von cstr2 -- eh nur default-konstruiert -- wird beim Entsorgen des temporären Objekts weggeworfen. cstr2 übernimmt die interne Repräsentation des von ToUpper zurückgegebenen Objektes.
Der Zuweisungsoperator kann nicht davon ausgehen, dass die rechte Seite nicht mehr gebraucht wird, muss also immer eine richtige Kopie machen (wenn wir COW wieder ausschließen)
-
menno.. sollte schlafen gehen. n8
-
Danke, dachte die linke Seite wird einfach als Parameter mitgegeben. Wusste nicht, das dass so kompliziert ist.. Aber wenn ich drüber nachdenke eigentlich logisch, das Objekt muss ja komplett neu konstruiert werden.
-
OK, dann hab ich jetzt noch ne Frage dazu:
int Dec(int a) { int r = a + 1; return r; } int main() { int f = 1; int g; g = Dec(f); ... }
Was passiert hier? Ist folgendes richtig?
1. Es wird ein int f auf dem Stack reserviert und mit dem Wert 1 gefüllt 2. Es wird ein int g auf dem Stack reserviert 3. Es wird ein int r auf dem Stack reserviert und mit dem Wert 2 gefüllt 4. Der Wert von r wird zu g [b]rüberkopiert[/b], so dass g mit 2 gefüllt wird 5. Der Speicher, den r belegte, wird wieder freigegeben
Zweite Frage: Was bedeutet const am Ende einer Funktionsdeklaration?
CString CString::ToUpper() const;
-
zu Frage 2:
Dieses const bedeutet IMHO, daß der Compiler den this-Zeiger als const this* an die Elementfunktion übergibt, d.h., die Funktion kann die Elemente der Klasse nicht verändern.Bitte korrigiert mich, wenn ich ich Unsinn erzähle, ist noch früh *gähn*
-
WebFritzi schrieb:
3. Es wird ein int r auf dem Stack reserviert und mit dem Wert 2 gefüllt
4. Der Wert von r wird zu g rüberkopiert, so dass g mit 2 gefüllt wird
5. Der Speicher, den r belegte, wird wieder freigegebenNein, eigentlich wird beim return zunächst ein temporäres Objekt erzeugt (als Kopie von r), dann wird r zerstört, und dann wird r (bzw. das temporäre Objekt) an g zugewiesen. Diese Erzeugung des temporären Objekts per Kopierkonstruktor kann mittels der schon angesprochenen Named Return Value Optimization (NRVO) vermieden werden. Was das ist, siehe Hume's FAQ: http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&faq=Optimize#Answ
Edit: Aber du arbeitest hier mit int-Objekten, die werden auch ganz gerne mal in Registern (%eax) zurückgegeben, da ist diese NRVO-Geschichte nicht wirklich von Belang
Zweite Frage: Was bedeutet const am Ende einer Funktionsdeklaration?
CString CString::ToUpper() const;
Das bedeutet, dass ToUpper die Membervariablen seines CString-Objektes nicht verändern kann. Das erlaubt es, diese Methode auch auf const-Objekte aufzurufen. Siehe dein Lieblings-C++-Lehrbuch (vom Level her gehören die beiden Fragen eigentlich nicht annähernd in denselben Thread :þ )
-
Nein, eigentlich wird beim return zunächst ein temporäres Objekt erzeugt (als Kopie von r), dann wird r zerstört, und dann wird r (bzw. das temporäre Objekt) an g zugewiesen
OK ich habe einen Stack. Da sind schon irgendwelche Werte drauf, die mich jetzt nicht interessieren. Dann werfe ich r drauf. Darauf lege ich ein temporäres Objekt. Jetzt habe ich ein Problem: Wie bekomme ich r vom Stack "gepopt", ohne vorher das temporäre objekt zu "popen".
-
Der Platz für den Rückgabewert wird schon vor dem Aufruf der Funktion freigemacht. Dh r liegt über dem temp-Objekt, und kann dann ganz normal runtergepoppt werden.
-
Ah, OK.