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, une const 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, . . .).