Frage zu C++: Funktion mit Referenz beim Rückgabewert

Gast #5033803
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
Gast #5033958
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
#5033990
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!
Persönliche Seite #5034046
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.
#5034870
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren