Forum: PC-Programmierung C++: Return value Klassenfunktion


von Walter T. (nicolas)


Angehängte Dateien:

Lesenswert?

Hallo,

ich arbeite mich gerade durch ein C++-Buch. Ich habe gerade ein 
Verständnisproblem mit den Übungen. (Die Quelltexte sind auch so im Netz 
herunterladbar, also wird es wohl kein Copyright-Problem mit meinen 
abgetippten Listings im Anhang geben.)

Meine Frage bezieht sich auf die Funktion in Zeile 95 der cpp-Datei. Es 
gibt eine ziemliche Häufung von Funktionen mit Namen add() 
unterschiedlicher Signatur.

Interessant für die Frage sind wohl
1
Rational add(Rational a, Rational b)
2
void Rational::add(Rational r)
Warum wählt der Compiler beim Ausdruck:
1
    Rational ai {Rational(a, 1)};
2
    return ai.add(b);
nicht die Funktion Rational add(Rational a, Rational b), zu der die 
Signatur passen würde, sondern die Funktion void Rational::add(Rational 
r), die keinen Rückgabewert liefert und damit nicht als Rvalue taugt?

: Bearbeitet durch User
von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Walter T. schrieb:

> Warum wählt der Compiler beim Ausdruck:
>
1
>     Rational ai {Rational(a, 1)};
2
>     return ai.add(b);
3
>
> nicht die Funktion Rational add(Rational a, Rational b), zu der die
> Signatur passen würde, sondern die Funktion void Rational::add(Rational
> r), die keinen Rückgabewert liefert und damit nicht als Rvalue taugt?

Ganz einfach. Die member function add() hat nur einen Parameter und ist 
eine member function. Im Beispiel wird explicit die member function 
syntax verwendet.

von Rolf M. (rmagnus)


Lesenswert?

Walter T. schrieb:
> Warum wählt der Compiler beim Ausdruck:    Rational ai {Rational(a, 1)};
>     return ai.add(b);
> nicht die Funktion Rational add(Rational a, Rational b), zu der die
> Signatur passen würde,

Weil da ein Member-Aufruf steht, aber die von dir genannte Funktion gar 
keine Memberfunktion ist. Damit die Funktion verwendet wird, müsste es 
heißen:
1
    return add(ai, b);

> sondern die Funktion void Rational::add(Rational r), die keinen
> Rückgabewert liefert und damit nicht als Rvalue taugt?

Der Rückgabetyp ist nicht Teil der Signatur und wird bei 
Funktionsüberladung nicht berücksichtigt.

: Bearbeitet durch User
von Walter T. (nicolas)


Lesenswert?

Wäre es sinnvoll, die Member-Funktion umzuschreiben, um sie als Rvalue 
nuetzen zu können, oder ist das unüblich?

von Andreas M. (amesser)


Lesenswert?

Bei einem Member der sich "add" nennt würde ich nicht unbedingt erwarten 
das der einen Rückgabewert hat. Zumal man dann nur erahnen könnte das 
bei
1
return ai.add(b)
auch das Objekt selbst angefasst wird.

Besser wäre es die Operatoren "+=" und "+" zu überladen. Die haben ein 
definiertes Verhalten was jeder kennt. (Und sind als RValue zu 
gebrauchen)

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Walter T. schrieb:
> Wäre es sinnvoll, die Member-Funktion umzuschreiben, um sie als Rvalue
> nuetzen zu können, oder ist das unüblich?

Das kann man schon machen:
1
   const Rational result = a.add(b);

Die member function entspricht ja dem += Operator, welcher eine 
Zuweisung ist und Zuweisung hat in C++ üblicherweise der Rückgabe-Typen 
Referenz auf ...:
1
   Rational& Rational::add(const Rational& rhs);

Üblicherweise nennt man die Dinger in C++ dann aber auch `operator+` 
bzw. `operator+=`. Dann kann ich eben auch:
1
   const Rational result = a += b;

schreiben.

von Wilhelm M. (wimalopaan)


Lesenswert?

Andreas M. schrieb:
> Zumal man dann nur erahnen könnte das
> beireturn ai.add(b)
> auch das Objekt selbst angefasst wird.

Jede non-const Elementfunktion ist in der Rolle eines Mutators (aka 
setter).

von Wilhelm M. (wimalopaan)


Lesenswert?

Torsten R. schrieb:
> Die member function entspricht ja dem += Operator, welcher eine
> Zuweisung ist und Zuweisung hat in C++ üblicherweise der Rückgabe-Typen
> Referenz auf ...:
>    Rational& Rational::add(const Rational& rhs);

Das ist durchaus üblich, weil man es auch bei primitiven Datentypen 
schreiben kann:

a += b += c;

oder in diesem Beispiel dann eben:

a += b += c;
a.add(b).add(c);

schreiben möchte (do as ints do). Aus dem Grunde ist der Rückgabe-Typ 
eine
LValue-Ref (kein RValue!).

Es ist einigermaßen weit verbreitet, Mutatoren verketten zu können. Sehr 
praktisch beim named-parameter-idiom.

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.