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();
}
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 ...