Forum: PC-Programmierung Frage zu C++: Funktion mit Referenz beim Rückgabewert


von NixGegenCPP (Gast)


Lesenswert?

Hi Leute,

ich versuche mich gerade in C++ einzuarbeiten und bin auf ein 
Verständnisproblem gestoßen, es geht um Funktionen mit Referenz als 
Rückgabewert. Auch nach längerem Rumsuchen gab es keine Erhellung. Hier 
der Quelltext:

Quelle: 
https://de.wikibooks.org/wiki/C%2B%2B-Programmierung/_Weitere_Grundelemente/_Referenzen



#include <iostream>
// gibt die Referenz des Parameters x zurück
int &zahl(int &x) {
    return x;
}

int main() {
    int y = 3;
    zahl(y) = 5;
    std::cout << "wert: " << y;
    return y;
}


Ausgabe:

wert: 5



Nach meinen Verständnis wird eine Funktion zahl() definiert, die als 
Eingabeparameter eine Referenz auf den Eingabeparameter beim Aufruf hat 
und als Rückgabewert einen int Wert liefert, wobei der Rückgabewert eine 
Referenz auf die interne Variable x ist.

Besondern unklar ist mir die Zeile

zahl(y) = 5;

Ich hätte erwartet, dass man schreibt

variable = zahl(y);

weil zahl() ja einen Rückgabewert hat. Andererseits ist zahl() eine 
Referenz, also hier ein Verweis auf x. Man wollte wohl zeigen, dass 
zahl() wie eine Variable behandelt werden kann.

Sinnfrei erscheint mir der Ausdruck

zahl(y) = 5;

auch deshalb, weil man auf zwei Arten auf die Funktion zahl() einwirkt,
einmal übergibt man mit y einen Wert und gleichzweitig erzwingt man, das 
zahl(y) einen anderen Wert annimmt.

konkrete Frage: wie ist zahl(y) = 5; zu verstehen?
konkrete Frage: gibt es ein besseres, plausibleres Beispiel für ein 
Funktion mit Referenz als Rückgabewert?

besten Dank für Eure Tipps.
NixGegenCPP

von Peter II (Gast)


Lesenswert?

NixGegenCPP schrieb:
> wobei der Rückgabewert eine
> Referenz auf die interne Variable x ist.

es gibt keine interne Variable! Es ist immer die gleiche Variabel weil 
nur mit Referenzen gearbeitet wird.

von NixGegenCPP (Gast)


Lesenswert?

Peter II schrieb:
> NixGegenCPP schrieb:
>> wobei der Rückgabewert eine
>> Referenz auf die interne Variable x ist.
>
> es gibt keine interne Variable! Es ist immer die gleiche Variabel weil
> nur mit Referenzen gearbeitet wird.

okay: falscher Zungenschlag von mir

von NixGegenCPP (Gast)


Lesenswert?

NixGegenCPP schrieb:

>
> konkrete Frage: wie ist zahl(y) = 5; zu verstehen?
> konkrete Frage: gibt es ein besseres, plausibleres Beispiel für ein
> Funktion mit Referenz als Rückgabewert?

hat trotzdem noch jemand eine Antwort?
NixGegenCPP

von Mikro 7. (mikro77)


Lesenswert?

Die Funktion hat keinen Kontext. Sie gibt einfach das Argument zurück. 
Genauso wie:
1
int foo(int i) { return i ; }

Referenzen haben viele Gemeinsamkeiten mit Zeigern. Vllt. hilft dir ja 
das weiter.
1
int* bar(int *p) { return p ; }
2
3
int i ; *(bar(&i)) = 5 ;

Edit: hier ein Beispiel aus der STL: 
http://en.cppreference.com/w/cpp/container/list/front

: Bearbeitet durch User
von NixGegenCPP (Gast)


Lesenswert?

Mikro 7. schrieb:


>
1
> int* bar(int *p) { return p ; }
2
> 
3
> int i ; *(bar(&i)) = 5 ;
4
>
>
Danke Mikro77,
ich verstehe, was es tut, in Referenzen (call by reference und 
Rückgabewert als Referenz) übertragen sollte das so aussehen:
1
int &bar(int &p) { return p; }
2
3
int i; bar(i) = 5;

über den Sinn kann man wahrscheinlich streiten: eine Funktion, die einen 
Rückgabewert liefert, der nicht zwangsläufig ausgewertet wird und auch 
noch von aussen gesetzt werden kann, wie bei einer Variablen, ohne dass 
der bar(Übergabeparameter) benutzt wird....
...NixGegenCPP

von Mikro 7. (mikro77)


Lesenswert?

NixGegenCPP schrieb:
> über den Sinn kann man wahrscheinlich streiten:

In der Form macht die Funktion nicht viel Sinn. Sie gibt ja einfach 
zurück, was ihr übergeben wurde. Solche Konstruktionen können aber als 
Verständnishilfe dienen.

> eine Funktion, die einen
> Rückgabewert liefert, der nicht zwangsläufig ausgewertet wird und auch

Ob der Rückgabewert genutzt wird oder nicht, dafür kann die Funktion 
nichts.

> noch von aussen gesetzt werden kann, wie bei einer Variablen, ohne dass

"Von aussen" wird nichts gesetzt. Schon einfach daher nicht, weil es in 
der Funktion kein "innen" gibt (es gibt keinen Kontext).

> der bar(Übergabeparameter) benutzt wird....

Der Parameter wird benutzt. Er wird ja zurückgegeben!

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das Beispiel ist ein bisschen beknackt, um das Prinzip zu erläutern.
1
class bla
2
{
3
private:
4
  int x;
5
public:
6
  bla() { x = 0; };
7
  ~bla() { };
8
9
  int& hepp() { return x; };
10
};
11
12
...
13
14
bla fusel;
15
16
printf("eins %d\n", fusel.hepp());
17
18
fusel.hepp() = 4;
19
20
printf("zwei %d\n", fusel.hepp());


Das macht das vielleicht verständlicher, welchen Sinn die Referenz als 
Rückgabewert einer Funktion haben kann.

von Klaus (Gast)


Lesenswert?

NixGegenCPP schrieb:
> konkrete Frage: gibt es ein besseres, plausibleres Beispiel für ein
> Funktion mit Referenz als Rückgabewert?

operator[]

von Wilhelm M. (wimalopaan)


Lesenswert?

Das macht man gern bei "settern" aka non-const Elementfunktionen:
1
class A {
2
public:
3
    int value() const {return mValue;}
4
    A& value(int v) {mValue = v; return *this;}
5
    A& feature(bool on) {mFeature = on; return *this;}
6
private:
7
    int mValue = 0;
8
    bool mFeature = false;
9
};
10
11
int main() {
12
    auto y = A().value(42).feature(true);
13
}

Damit ist eine Verkettung der "setter" möglich. Das läuft auch unter 
"named-parameter idiom".

Natürlich kann man nur Objekte per-ref zurückgeben, die noch existieren. 
Im Beispiel oben ist das für die Member erfüllt, oder auch für 
ref-Parameter einer Funktion, eine lokale Variable darf man natürlich 
nicht per ref zurückgeben (Regel ref-in/ref-out ist ok).

In C++ sind Referenzen am besten als Alias-Name oder Synonym für ein 
anderes benanntes Objekt zu sehen. Das hilft beim Verständnis.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.