Programmer en C++
Les classes : Auto-référence

1. Auto-référence : this

Pour comprendre le réel intérêt de ce pointeur "this", nous allons partir de l'exemple suivant :

// Déclaration d'une classe nommée Boite
class Boite
{
private:
    double longueur;
    double largeur;
    double hauteur;
public:
    Boite(double, double, double);     // Constructeur
    double volume();
    bool compare(Boite);
};

Inutile de chercher "this" ici, il n'est pas encore présent. Je prépare juste le terrain en déclarant une classe Boite, possédant trois variables membres destinée à contenir ses dimensions. On y trouve également un constructeur pour initialiser chaque boite, et deux fonctions membres que nous allons détailler.
Les définitions du constructeur et de la fonction calculant le volume de la boite ne pose aucun problème :

// Surtout ne pas utiliser "long" ici qui est un type réservé.
Boite::Boite(double lon, double larg, double haut)     // Constructeur
{
    longueur = lon;
    largeur = larg;
    hauteur = haut;
}

double Boite::volume()
{
    return longueur * largeur * hauteur;
}

Celà ne va pas être le cas pour la fonction compare(...). En effet supposons que nous ayons créé deux boites :

Boite boite1(5.2, 3.0, 2.4);
Boite boite2(4.0, 3.2, 1.5);

Il est facile de transmettre par exemple la boite2 en argument dans la fonction compare(...) :

compare(boite2);

et tout aussi facile d'obtenir dans cette fonction, le volume de cette boite en écrivant :

boite2.volume();

Certains diraient : et alors ou est le problème ? on n'a qu'a transmettre aussi la boite1 en argument, et calculer son volume de la même façon. En effet celà marcherait.
Vous n'auriez pas oublié qu'une fonction membre est appelée par un objet (une instance) de la classe ? Il est donc logique que nous l'appelions avec boite1, puisqu'elle a déjà tout ce qu'il lui faut avec boite2 (la boite transmise en argument).
Je parie qu'à cet instant vous vous dites : j'ai compris, il n'y qu'à écrire dans la fonction compare(...) :

boite1.volume();

Malheureusement celà ne va pas marcher ! Pourquoi ?
Comme boite1 ne fait pas partie des arguments, elle est vue dans la fonction comme une variable interne qui de plus n'aurait été ni déclarée (aucun type) ni initialisée. Autrement dit vous venez de créer une erreur. C'est une impasse ?

Justement non, car c'est ici que ce fameux pointeur "this" a été créé pour nous tirer de ce mauvais pas. Il contient l'adresse de l'objet ayant appelé la fonction compare(...), et donc va nous permettre d'appeler la fonction volume() tout en lui transmettant les variables membres de la boite1.
C'est un peu compliqué dit comme ça, et on reformulera en disant plus simplement que nous allons remplacer la ligne "boite1.volume();" qui ne fonctionne pas, par :

this->volume();

Grace à ce pointeur nous pouvons maintenant écrire la définition de notre fonction compare(...) :

bool Boite::compare(Boite boite)
{
    return boite.volume()   >   this->volume();
}

Découvrons maintenant le programme complet :

#include <iostream>

using namespace std;


class Boite     // Déclaration de la classe Boite
{
private:
    double longueur;
    double largeur;
    double hauteur;
public:
    Boite(double, double, double);     // Constructeur
    double volume();
    bool compare(Boite);
};

int main()
{
    Boite boite1(5.2, 3.0, 2.4);
    Boite boite2(6.1, 3.5, 1.8);
    if (boite1.compare(boite2))
        cout << "La boite 2 est plus volumineuse" << endl;
    else
        cout << "La boite 2 n'est pas plus volumineuse" << endl;
    return 0;
}

// Surtout ne pas utiliser "long" ici qui est un type réservé.
Boite::Boite(double lon, double larg, double haut)     // Constructeur
{
    longueur = lon;
    largeur = larg;
    hauteur = haut;
}

double Boite::volume()
{
    return longueur * largeur * hauteur;
}

bool Boite::compare(Boite boite)
{
    return boite.volume()   >   this->volume();
}

2. Autre cas d'utilisation de "this"

Certains programmeurs trouvent que l'utilisation de "this" procure plus de clarté, et aurait écrit la définition de notre constructeur de cette façon :

Boite::Boite(double lon, double larg, double haut)     // Constructeur
{
    this->longueur = lon;
    this->largeur = larg;
    this->hauteur = haut;
}

A chacun de voir ...