logo

puntatore 'questo' in C++

Per comprendere il puntatore 'questo', è importante sapere come gli oggetti guardano le funzioni e i dati membri di una classe.

  1. Ogni oggetto ottiene la propria copia del membro dati.
  2. 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;> }>

>

>