Per comprendere il puntatore 'questo', è importante sapere come gli oggetti guardano le funzioni e i dati membri di una classe.
- Ogni oggetto ottiene la propria copia del membro dati.
- Tutti accedono alla stessa definizione di funzione presente nel segmento di codice.
Ciò significa che ogni oggetto ottiene la propria copia dei membri dati e tutti gli oggetti condividono una singola copia delle funzioni membro.
Quindi ora la domanda è: se esiste una sola copia di ciascuna funzione membro e viene utilizzata da più oggetti, come si accede e si aggiornano i membri dati corretti?
Il compilatore fornisce un puntatore implicito insieme ai nomi delle funzioni come 'questo'.
Il puntatore 'this' viene passato come argomento nascosto a tutte le chiamate di funzioni membro non statiche ed è disponibile come variabile locale all'interno del corpo di tutte le funzioni non statiche.Il puntatore 'this' non è disponibile nelle funzioni membro statiche poiché le funzioni membro statiche possono essere chiamate senza alcun oggetto (con il nome della classe).
Per una classe X, il tipo di questo puntatore è 'X*'. Inoltre, se una funzione membro di X è dichiarata come const, il tipo di questo puntatore è 'const X *' (vedi questo GFact )
Nella prima versione del C++ era possibile modificare il puntatore 'questo'; in questo modo un programmatore potrebbe cambiare su quale oggetto sta lavorando un metodo. Questa funzionalità è stata infine rimossa e ora in C++ è un valore r.
C++ consente agli oggetti di distruggersi chiamando il seguente codice:
delete> this>;> |
>
>
Come ha affermato Stroustrup, 'questo' potrebbe essere il riferimento rispetto al puntatore, ma il riferimento non era presente nella prima versione di C++. Se 'questo' viene implementato come riferimento, il problema di cui sopra potrebbe essere evitato e potrebbe essere più sicuro del puntatore.
Di seguito sono riportate le situazioni in cui viene utilizzato il puntatore 'questo':
1) Quando il nome della variabile locale è uguale al nome del membro
#include> using> namespace> std;> > /* local variable is same as a member's name */> class> Test> {> private>:> >int> x;> public>:> >void> setX (>int> x)> >{> >// The 'this' pointer is used to retrieve the object's x> >// hidden by the local variable 'x'> >this>->x = x;> >}> >void> print() { cout <<>'x = '> << x << endl; }> };> > int> main()> {> >Test obj;> >int> x = 20;> >obj.setX(x);> >obj.print();> >return> 0;> }> |
>
>
Produzione:
x = 20>
Per i costruttori, elenco degli inizializzatori può essere utilizzato anche quando il nome del parametro è uguale al nome del membro.
2) Per restituire il riferimento all'oggetto chiamante
/* Reference to the calling object can be returned */> Test& Test::func ()> {> >// Some processing> >return> *>this>;> }> |
>
>
Quando viene restituito un riferimento a un oggetto locale, è possibile utilizzare il riferimento restituito chiamate di funzioni a catena su un unico oggetto.
#include> using> namespace> std;> > class> Test> {> private>:> >int> x;> >int> y;> public>:> >Test(>int> x = 0,>int> y = 0) {>this>->x = x;>this>->y = y; }> >Test &setX(>int> a) { x = a;>return> *>this>; }> >Test &setY(>int> b) { y = b;>return> *>this>; }> >void> print() { cout <<>'x = '> << x <<>' y = '> << y << endl; }> };> > int> main()> {> >Test obj1(5, 5);> > >// Chained function calls. All calls modify the same object> >// as the same object is returned by reference> >obj1.setX(10).setY(20);> > >obj1.print();> >return> 0;> }> |
>
>
Produzione:
x = 10 y = 20>
Esercizio:
Prevedere l'output dei seguenti programmi. Se ci sono errori di compilazione, correggili.
Domanda 1
#include> using> namespace> std;> > class> Test> {> private>:> >int> x;> public>:> >Test(>int> x = 0) {>this>->x = x; }> >void> change(Test *t) {>this> = t; }> >void> print() { cout <<>'x = '> << x << endl; }> };> > int> main()> {> >Test obj(5);> >Test *ptr =>new> Test (10);> >obj.change(ptr);> >obj.print();> >return> 0;> }> |
>
>
Domanda 2
#include> using> namespace> std;> > class> Test> {> private>:> >int> x;> >int> y;> public>:> >Test(>int> x = 0,>int> y = 0) {>this>->x = x;>this>->y = y; }> >static> void> fun1() { cout <<>'Inside fun1()'>; }> >static> void> fun2() { cout <<>'Inside fun2()'>;>this>->divertimento1(); }> };> > int> main()> {> >Test obj;> >obj.fun2();> >return> 0;> }> |
>
>
Domanda 3
mylivecricket.
#include> using> namespace> std;> > class> Test> {> private>:> >int> x;> >int> y;> public>:> >Test (>int> x = 0,>int> y = 0) {>this>->x = x;>this>->y = y; }> >Test setX(>int> a) { x = a;>return> *>this>; }> >Test setY(>int> b) { y = b;>return> *>this>; }> >void> print() { cout <<>'x = '> << x <<>' y = '> << y << endl; }> };> > int> main()> {> >Test obj1;> >obj1.setX(10).setY(20);> >obj1.print();> >return> 0;> }> |
>
>
Domanda 4
#include> using> namespace> std;> > class> Test> {> private>:> >int> x;> >int> y;> public>:> >Test(>int> x = 0,>int> y = 0) {>this>->x = x;>this>->y = y; }> >void> setX(>int> a) { x = a; }> >void> setY(>int> b) { y = b; }> >void> destroy() {>delete> this>; }> >void> print() { cout <<>'x = '> << x <<>' y = '> << y << endl; }> };> > int> main()> {> >Test obj;> >obj.destroy();> >obj.print();> >return> 0;> }> |
>
>