return Referenz und *this??
-
hi,
ich lerne grad c++ und bin auf etwas gestoßen ,was ich nicht ganz verstehe.
Was passiert genau wenn ich eine Funktion definiere, die eine Referenz als Rückgabe enthält (ich hab schon gegooglet und das Forum hier durchsucht, ich finde aber keine Antwort mit der ich das richtig verstehe)? In meinem Lehrbuch soll an einer stelle ein operator so überladen werden, dass man eine klasse bequem über cout ausgeben kann.die klasse sieht ungefähr so aus :
class cZeit { private: int _hour; int _min; int _sec; public: cZeit() {}; cZeit(int hour, int min, int sec=0) { _hour = hour; _min = min; _sec = sec; } cZeit addieren(cZeit zeit); int getHour() {return _hour;} int getMin() {return _min;} };Um dann jetzt die Daten der Klasse ausgeben zu können, soll der << operator überladen werden. also cout << Objekt soll die daten ausgeben. In einfacher Form sieht das dann ungefähr so aus(ist als friend-Funktion in der Klasse noch drin, müsste noch eingefügt werden):
ostream & operator<< (ostream &ausgabe, const cZeit &z) { ausgabe << "stunde: " << z._hour << "\nminute: " << z._min << endl; return ausgabe; }Wenn ich jetzt entweder bei &operator<< oder bei &ausgabe es nicht als referenz schreibe, kommt ein fehler
Fehler 2 error C2248: "std::basic_ios<_Elem,_Traits>::basic_ios": Kein Zugriff auf private Member, dessen Deklaration in der std::basic_ios<_Elem,_Traits>-Klasse erfolgte.Was also genau geschieht wenn die Funktion eine Referenz zurückgibt (und warum muss cout als referenz übernommen werden)?
Außerdem was genau bedeutet es wenn man am ende einer methode
return *thiswiedergibt? In dem Buch wird gesagt, dass man eine Referenz auf das bearbeitete Objekt wiedergibt oder ist es doch nur eine Kopie?
Sorry wenn ich zuviele Fragen stelle, aber ich würds gerne verstehen

grüße
-
Mist jetzt hab ich vermutlich ien zu spezielles Beispiel gegeben...
Wenn mir jemand sagen kann was genau bei der Referenz-Rückgabe passiert wäre ich schon ein Stück weiter...grüße
-
Weißt du was eine Referenz ist?
Letztendlich ist die Rückgabe einer Referenz nicht anders als jede beliebige andere Rückgabe auch. Nur das hier eben eine Referenz auf die entsprechende Variable zurückgegeben wird.
Es findet hier also keine Kopie statt. Weiterhin kann der Aufrufer der Funktion den Rückgabewert ändern.
Beim ostream-Operator<< ist die Referenz einfach nötig weil ostream nicht kopierbar ist und man will die operatoren ja verketten können.
-
orolindu schrieb:
Wenn mir jemand sagen kann was genau bei der Referenz-Rückgabe passiert wäre ich schon ein Stück weiter...
Grundsätzlich ist eine Referenz nur ein Aliasname für ein Objekt. Bei einer Referenzrückgabe wird das jeweilige Objekt also zurückgegeben, ohne eine Kopie zu erzeugen.
"return *this" erzeugt daher nur dann eine Kopie, wenn man keine Referenz sondern eine Werteübergabe macht.
Hintergrund für Referenzübergaben ist, das man auf dem gleichen Objekt weiterarbeiten und dabei Aufrufe verketten kann. z.B. um immer auf den gleichen Stream auszugeben...
Gefährlich sind wiederum Referenzrückgaben von lokalen Variablen, da diese mit dem Verlassen der Funktion ungültig werden.
-
erstmal danke für eure hilfe!
also was eine referenz ist, habe ich mittlerweile verstanden.
@asc: dein letzter satz ist auch das, was mich beim rumprobieren etwas stutzig gemacht hat
int& rechen(int b){ b += 1; return b; }da gebe ich ja quasi die referenz auf meine temporäre variable b aus.
so würde ich ja eine referenz auf b ausgeben, die ihrerseits eine referenz auf die eingelesene variable ist:
int& rechen(int& b){ b += 1; return b; }das erste dürfte meiner logik nach ja gar nicht gehen, da b nach verlassen derfunktion eigentlich nicht mehr existieren sollte. beim zweiten ist es doch lediglich eine zweifache referenz auf das eigentliche objekt...
-
Das ist korrekt.
-
orolindu schrieb:
@asc: dein letzter satz ist auch das, was mich beim rumprobieren etwas stutzig gemacht hat
Nicht alles was scheinbar funktioniert ist auch richtig. In diesem Fall hattest du Glück, das der Speicherbereich noch nicht anderweitig verwendet wurden ist, und die Laufzeitumgebung oder das OS nicht bei dem Zugriff einen Strich durch die Rechnung gemacht hat.
Dein Beispiel ist klassisches "undefiniertes Verhalten", und zieht die am schwersten zu findenden Fehler nach sich (da nicht "reproduzierbar").
-
Ne, wieso zweifach? Im zweiten Beispiel hast Du nur eine einzige Referenz auf einen int-Wert; nicht etwa eine Referenz auf eine Referenz ... geht das überhaupt?
-
Ups, stimmt, das habe ich falsch verstanden. Es sind lediglich zwei Referenzen.
Und eine Referenz auf eine Referenz gibt es nicht, weil Referenzen nicht geändert werden können und das somit überhaupt keinen Sinn macht.
-
ah, ok gut!
danke nochmal für alles!