Références et const.
Quelques tests
Faisons quelques tests simples sur les références. Créer un programme ref.cpp
(qui ne servira pas dans la suite) avec une fonction main
.
Les bases
Dans le main
, créer avec une variable int i
initialisée à la valeur 99. Créer une référence ri
sur cette variable.
Afficher l’adresse et la valeur de i
puis l’adresse et la valeur de ri
.
Compiler et exécuter.
Ajouter à la suite une variable int j
initialisée à 66 puis ajouter l’instruction ri=j
.
Afficher l’adresse et la valeur de i
, l’adresse et la valeur de ri
et l’adresse et la valeur de j
.
Paramètre de fonction
Dans le code ci-dessus, ajouter une fonction foo
qui prend un entier x
par référence et qui renvoie un entier égal à x+2
.
Dans la fonction foo
, afficher l’adresse et la valeur de x
.
Appeler foo
avec ri
en paramètre.
Compiler et exécuter.
Créer une nouvelle référence rx
, initialisée à partir de la valeur de retour de foo
.
Compiler et expliquer.
Modifier foo
pour que celle-ci incrémente x
de 2
puis retourne x
. Faites en sorte que le code juste avant fonctionne.
Afficher l’adresse et la valeur de rx
.
Tableaux
Ajouter maintenant un tableau d’entier int tab[10]={4}
. Créer une référence t2
sur la case t[2]
du tableau.
Afficher l’adresse et la valeur de t2
.
Créer un fonction settab
qui prend la tableau, un indice et une valeur en paramètre et qui affecte la valeur à la case du tableau. Afficher la valeur et l’adresse de cette case puis retourne un référence sur cette case.
Créer une référence t2b
à partir de settab(tab,2,6)
.
Afficher l’adresse et la valeur de t2
et t2b
.
Suite
Il est fortement conseillé de faire des petits tests comme ceux ci-dessus (ajouter les pointeurs, utiliser des instances de classes, allocation dynamique…) jusqu’à avoir bien assimilé le concept de référence.
Nous reprenons la suite du td précédent avec les CharSequence
Passage par référence
Modifier la fonction foo
dans le fichier program.cpp
pour que l’instance de CharSequence
soit prise par référence.
Compiler et exécuter. Combien d’instances sont créées au finale ?
Passage par référence constante
Dans la fonction foo
, afficher la valeur de retour de la méthode length
en utilisant printf
.
Compiler, exécuter.
Modifier la référence pour qu’elle soit constante :
void foo( const CharSequence & s )
Compiler et lire attentivement le message du compilateur.
Pour finir, dans la classe CharSequence
, indiquez que la méthode length
ne modifiera pas les attributs de this
(le site d’appel). Pour cela, ajouter le mot clé const
après les arguments :
unsigned int length () const ;
Ce qualificatif fait parti de la signature de la méthode, il faut donc l’indiquer dans le fichier CharSequence.hpp
et CharSequence.cpp
.
Compiler. Qu’en déduisez vous sur le fonctionnement de const
?
Régles de programmation :
D’une façon générale, il faut toujours mettre le
const
sur la méthode et les références. La question que vous devez vous poser est : “vais-je modifier l’objet ?”. Si vous répondez oui, alors on ne met pas le const, si vous répondez non, alors on laisse le const (puisqu’on venait de le mettre par reflexe).
Dans le cas des méthodes d’instance, il peut arriver que l’on souhaite avoir deux comportements différents selon que la source (l’objet sur lequel on appelle la méthode) est constante ou non. Cela ne pose pas de problème étant donné que l’attribut
const
des méthodes fait parti de la signature : on écrira donc deux versions de la méthode, uneconst
et l’autre non.
A partir de maintenant tous les arguments d’une fonction seront soit des références, soit des pointeurs, soit des types primitifs (int, char, . . .).