C++: Return value Klassenfunktion

OP #6495410
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?
Angehängte Dateien:
(Firma: Torrox.de) #6495416
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.
#6495417
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.
#6495429
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)
(Firma: Torrox.de) #6495439
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.
#6496020
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.

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