LucaLuca (Normal User)
Newbie
Messaggi: 15
Iscritto: 25/06/2011
|
Apro una nuova discussione...essendo nuovo del forum non sapevo della differenza tra domanda e discussione e dell'impossibilità di rispondere solo attraverso commenti delle domande. Dovendo porre ulteriori domande e inserire anche del codice mi era impossibile continuare nel precedente post.
Quoto:
Salve a tutti,
sto leggendo il libro "C++ Fondamenti di programmazione" di Deitel. Un paragrafo porta in esame il puntatore this. Premesso che quanto letto prima l'ho appreso chiaramente (per intenderci, il concetto di puntatore mi è chiaro) vorrei chiedervi alcune delucidazioni a riguardo.
I miei dubbi sono innanzitutto concettuali. Vi riporto parte del testo
"Ogni oggetto può accedere al proprio indirizzo tramite un puntatore di nome this. [...] Il puntatore this viene usato implicitamente per riferire sia i dati che le funzioni membro di un oggetto, e può essere anche utilizzato esplicitamente"
In particolare l'ultima parte non mi è chiara. Vi chiedo gentilmente di spiegarmi questo puntatore o in alternativa di postare link a guide online.
Grazie milleee
P.S. Ho già cercato su google ma non ho trovato nulla di soddisfacente
Edit: Naturalmente anche guide in lingua inglese, non necessariamente italiano
RISPOSTA PieroTofy:
Quando fai riferimento ad una variabile membro oppure ad un metodo dall'interno della classe che lo contiene:
Codice sorgente - presumibilmente C++ |
class A{ private: int i; void f1(){ i = 0; // <-- esempio } void f2(){ f1(); // <--- esempio } };
|
Durante la fase di parsing il compilatore riconoscerà che i membri fanno parte della stessa classe e aggiungerà:
Codice sorgente - presumibilmente C/C++ |
void f1(){
(*this).i = 0;
}
void f2(){
(*this).f1();
}
|
Ovviamente i (*this) sono impliciti e sarebbe ridondanti scriverli, quindi il compilatore si fa carico di inserirli al posto tuo. Ma se vuoi scriverli esplicitamente te stesso (come nel secondo pezzo di codice), puoi farlo. Ultima modifica effettuata da LucaLuca il 25/06/2011 alle 18:10 |
|
LucaLuca (Normal User)
Newbie
Messaggi: 15
Iscritto: 25/06/2011
|
Fin qui tutto chiaro...
posto ora parte di un programma esempio che sfrutta il puntatore this per effettuare chiamate a cascata attraverso l'operatore .
DEFINIZIONE CLASSE TIME
Codice sorgente - presumibilmente C++ |
#include "Time.h" Time::Time (int hr, int min, int sec) { setTime (hr,min,sec); } Time &Time::setTime(int h, int m, int s) { setHour(h); setMinute(m); setSecond(s); return *this; } Time &Time::setHour(int h) { CODICE DI VERIFICA ORA return *this; } Time &Time::setMinute(int m) { CODICE DI VERIFICA MINUTO return *this; } Time &Time::setSecond(int s) { CODICE DI VERIFICA SECONDO return *this; }
|
MAIN PROGRAM
Codice sorgente - presumibilmente C/C++ |
#include "Time.h"
int main()
{
Time t;
t.setHour(18).setMinute(20).setSecond(29);
}
|
(se necessario posterò anche il prototipo della classe. Si noti che le variabile hour, minute, second sono dichiarate come interi privati all'interno della classe.)
t.setHour(18).setMinute(20).setSecond(29);
Questa espressione mi è chiara: restituendo le tre funzioni un riferimento all'oggetto è come se scrivessi:
t.setHour(18) => t.setMinute(20) => ecc..
e quindi ottengo la chiamata a cascata come voluto.
Non capisco in realtà la funzione setTime. Una volta che la funzione a chiamato setHour quest'ultima restituisce un riferimento ad un oggetto. Non dovrebbe restituire 0 in uscita? Perchè si deve resitutire un riferimento all'oggetto? Come viene gestito dal compilatore?
Grazie mille!
|
|
lumo (Member)
Expert
Messaggi: 449
Iscritto: 18/04/2010
|
Codice sorgente - presumibilmente C/C++ |
Time &Time::setTime(int h, int m, int s)
{
setHour(h);
setMinute(m);
setSecond(s);
return *this;
}
|
In questo caso, il risultato di setHour, setMinute e setSecond non viene usato. Non so precisamente come lo gestisca il compilatore, ma penso che invece di salvare il risultato come sarebbe facendo Time& t = setHour(h); lo scarti
Comunque il metodo in questo caso è riscrivibile così:
Codice sorgente - presumibilmente C/C++ |
return setHour(h).setMinute(m).setSecond(s);
|
In effetti il ritornare un reference da setTime() non pare molto intelligente, però ipotizznado che ci siano altri metodi nella classe potrebbe essere utile per fare
Codice sorgente - presumibilmente Plain Text |
t.setTime(...).altro_metodo();
|
Ultima modifica effettuata da lumo il 25/06/2011 alle 19:43 |
|
LucaLuca (Normal User)
Newbie
Messaggi: 15
Iscritto: 25/06/2011
|
Codice sorgente - presumibilmente C/C++ |
return setHour(h).setMinute(m).setSecond(s);
|
Non ho capito...tu intendi dire che la funzione setTime sia riducibile a questo codice?
In realtà il mio dubbio maggiore è proprio sul tipo di ritorno...
Codice sorgente - presumibilmente Plain Text |
Time &Time::setHour(int h)
|
Restituisce un oggetto Time in uscita...ma qual è il senso di una referenza &Time?
Se io avessi avuto funzioni set del tipo
Codice sorgente - presumibilmente C/C++ |
utilizzate all'interno della funzione come nel codice postato avrei messaggio di errore visto che il risultato di uscita della funzione non viene coinvolto in nessuna operazione?
Ultima modifica effettuata da LucaLuca il 26/06/2011 alle 0:22 |
|
lumo (Member)
Expert
Messaggi: 449
Iscritto: 18/04/2010
|
Postato originariamente da LucaLuca:
Codice sorgente - presumibilmente C/C++ |
return setHour(h).setMinute(m).setSecond(s);
|
Non ho capito...tu intendi dire che la funzione setTime sia riducibile a questo codice?
In realtà il mio dubbio maggiore è proprio sul tipo di ritorno...
Codice sorgente - presumibilmente Plain Text |
Time &Time::setHour(int h)
|
Restituisce un oggetto Time in uscita...ma qual è il senso di una referenza &Time?
setHour() è dichiarata appunto con tipo di ritorno Time& per permettere le chiamate a cascate.
Se io avessi avuto funzioni set del tipo
Codice sorgente - presumibilmente C/C++ |
utilizzate all'interno della funzione come nel codice postato avrei messaggio di errore visto che il risultato di uscita della funzione non viene coinvolto in nessuna operazione?
Eh no. E' perfettamente lecito chiamare una funzione e non usarne il valore di ritorno; lo fai anche tu nel codice che hai postato:
t.setHour(18).setMinute(20).setSecond(29);
Questa espressione mi è chiara: restituendo le tre funzioni un riferimento all'oggetto è come se scrivessi:
t.setHour(18) => t.setMinute(20) => ecc..
infatti l'ultimo metodo che chiami, setSecond(), ritorna anche un reference a *this che per tu non usi.
Un altro esempio migliore, se ti è mai capitato di usarla, è la funzione printf()
Di solito la trovi così:
Codice sorgente - presumibilmente Plain Text |
Ma in realtà il prototipo di printf è int printf ( const char * format, ... );
Ultima modifica effettuata da lumo il 26/06/2011 alle 10:54 |
|
LucaLuca (Normal User)
Newbie
Messaggi: 15
Iscritto: 25/06/2011
|
Capito..i dubbi si riducono
Ultima domanda e dopo ho capito vita morte e miracoli del this ...
Nelle funzioni utilizzate mantengo lo schema
Time &Time::nomeFunzione (parametri)
Perchè si utilizza &Time anzichè Time nella definizione delle funzioni?
|
|
lumo (Member)
Expert
Messaggi: 449
Iscritto: 18/04/2010
|
Postato originariamente da LucaLuca:
Capito..i dubbi si riducono
Ultima domanda e dopo ho capito vita morte e miracoli del this ...
Nelle funzioni utilizzate mantengo lo schema
Time &Time::nomeFunzione (parametri)
Perchè si utilizza &Time anzichè Time nella definizione delle funzioni? |
in quella definizione & non riguarda la parte che viene dopo( Time:: ), bensì riguarda al tipo di ritorno:
Time &Time::nomeFunzione( parametri );
significa che il tipo del valore di ritorno è Time&, cioè un reference ad un'istanza di Time. Il fatto che l'& sia attaccato a nome del metodo è solo una questione di (non) stile.
Ovviamente il reference è necessario affinchè venga modificato l'oggetto su cui si chiama la funzione "a cascata" e non l'oggetto copiato. |
|