PDA

Visualizza la versione completa : [C++] Classi e metodi costanti


Narsil_
04-08-2015, 13:38
Salve a tutti. Stavo provando a fare un esercizio di C++ riguardante classi e metodi e mi sono bloccato in un punto. La richiesta è dire se le istruzioni del main compilano o meno.



class C
{
private:
int x;
public:
C(int n=0){x=n;}
C G (C obj) const {C r; r.x=obj.x+x; return r;}
C H (C& obj) {obj.x+=x; return obj;}
C I (const C& obj) {C r; r.x=obj.x+x; return r;}
C J (const C& obj) const {C r; r.x=obj.x+x; return r;}
};

int main()
{
C x, y(1), z(2); const C v(2);
x.H(z.G(y)); // (7)
x.I(z.G(y)); // (8)
x.J(z.G(y)); // (9)
v.J(z.G(y)); // (10)
}


Ho provato a compilare e il risultato è che la numero 7 non compila, mentre le altre sì. Qualcuno è in grado di spiegarmi il perchè? Mi è venuto in mente che z.G(y) restituisce un tipo C per valore, mentre H ha come parametro formale un tipo C per riferimento, quindi quando invoco x.H gli sto passado solo un valore e non una variabile completa. Ma secondo questo ragionamento dovrebbero essere sbagliate anche le istruzioni successive, ma il compilatore dice altrimenti. Sono completamente fuori strada?
Grazie in anticipo

MItaly
04-08-2015, 14:51
La 7 non compila perché G restituisce per valore e H vuole un reference non-const, dal momento che i reference non-const non possono agganciare valori temporanei (in generale, fino al C++11 non si può avere un reference non-const ad un rvalue; poi con la move semantics, gli xvalue e gli universal references un po' di queste cose sono cambiate, ma per ora non farci caso).
L'idea di fondo, comunque, vorrebbe essere che non ha senso passare come modificabile un valore che al termine di questa espressione va a morire (poi possiamo discutere di quanto questa regola ha davvero senso, ma tant'è).

Narsil_
04-08-2015, 15:03
Ok, mentre le invocazioni successive accettano tranquillamente un r-valore, avendo come parametro formale un reference const, quindi non modificabile dal corpo della funzione, esatto?
Grazie mille della risposta.

MItaly
04-08-2015, 15:40
Esatto; si può dire che i const reference hanno una "deroga speciale" e possono bindare anche gli rvalue (se così non fosse sarebbero sostanzialmente inusabili come parametri per funzioni, dato che non sarebbe possibile passare il valore di ritorno di una funzione o un oggetto costruito al volo come argomento di un'altra funzione).

Narsil_
04-08-2015, 16:03
Tutto chiaro, grazie ancora per la risposta.

MItaly
04-08-2015, 17:18
:ciauz:

Loading