La specifica del linguaggio C++ include la parola riservata this
, il cui uso è esclusivamente confinato all'ambito della definizione dei metodi di una classe.
In tale contesto, infatti, this
identifica un puntatore speciale che contiene l'indirizzo dell'istanza della classe che ha invocato il metodo.
L'inizializzazione del puntatore this
è a carico del compilatore, che include il codice necessario nei costruttori di ogni classe e che aggiunge il puntatore this
come parametro implicito di ogni funzione membro a eccezione dei metodi statici.
Il tipo del puntatore this
è quello di un puntatore alla classe. Ad esempio, se definiamo una classe di nome X, il tipo del puntatore this
nel contesto di tale classe è X*.
Il puntatore this
ha un ruolo fondamentale nella definizione di alcuni metodi speciali, come gli operatori di assegnamento, di copia e di spostamento, poiché viene usato esplicitamente per la restituzione del valore di ritorno.
Inoltre, esso è anche usato in maniera implicita ogni qual volta si faccia riferimento ad un dato membro di una classe all'interno di un metodo non statico. In questo caso, infatti, è il compilatore che aggiunge automaticamente il codice necessario alla referenziazione di tale membro a partire da this
, come illustrato nel listato seguente.
#include <iostream>
class X :
{
public:
void print_a()
{
std::cout << a << std::endl; // diventa this->a
}
void set_a(int a)
{
this->a = a; // attenzione: usare a = a; lascerebbe il membro di classe X::a inalterato.
}
private:
int a;
};
A volte inoltre, il puntatore this
può essere usato per referenziare un membro di classe il cui nome è "oscurato" da quello di un argomento omonimo, come ad esempio accade nella funzione membro set_a()
.
Quando il puntatore this
è usato come parametro implicito di metodi const, ad esso viene applicato il qualificatore const
, garantendo così che nell'ambito di tale metodo tutti i membri della classe siano non modificabili.
L'uso del puntatore this
è molto spesso opzionale, o meglio demandato al compilatore, ed è necessario solo in alcuni casi specifici, come quelli illustrati in precendenza.
Prima di concludere, è bene ricordare che this
è un membro di classe a tutti gli effetti, che può anche essere ereditato. Analogamente a quanto avviene con la tabella dei metodi virtuali, esso viene quindi reinizializzato nei costruttori delle classi derivate. Particolare attenzione quindi deve essere rivolta al caso dell'invocazione di metodi virtuali nel corpo di istruzioni del costruttore delle classi base. In questo caso, infatti, non è garantito che l'associazione dinamica dei metodi sia funzionale, poichè l'oggetto derivato non è ancora completamente costruito.