'>

l'objet en C sharp: Les références d'objets + Passage de paramètres de type référence d'objet + Les objets temporaires

 2.1.10 Les références d'objets
Nous utilisons toujours la même classe Personne. Le programme de test devient le suivant :
1. using System;
2.
3. namespace Chap2 {
4. class Program2 {
5. static void Main() {
6. // p1
7. Personne p1 = new Personne("Jean", "Dupont", 30);
8. Console.Write("p1="); p1.Identifie();
9. // p2 référence le même objet que p1
10. Personne p2 = p1;
11. Console.Write("p2="); p2.Identifie();
12. // p3 référence un objet qui sera une copie de l'objet référencé par p1
13. Personne p3 = new Personne(p1);
14. Console.Write("p3="); p3.Identifie();
15. // on change l'état de l'objet référencé par p1
16. p1.Initialise("Micheline", "Benoît", 67);
17. Console.Write("p1="); p1.Identifie();
18. // comme p2=p1, l'objet référencé par p2 a du changer d'état
19. Console.Write("p2="); p2.Identifie();
20. // comme p3 ne référence pas le même objet que p1, l'objet référencé par p3 n'a pas du
changer
21. Console.Write("p3="); p3.Identifie();
22. }
23. }
24.}
Les résultats obtenus sont les suivants :
1. p1=[Jean, Dupont, 30]
2. p2=[Jean, Dupont, 30]
3. p3=[Jean, Dupont, 30]
4. p1=[Micheline, Benoît, 67]
5. p2=[Micheline, Benoît, 67]
6. p3=[Jean, Dupont, 30]

Lorsqu'on déclare la variable p1 par
Personne p1=new Personne("Jean","Dupont",30);
p1 référence l'objet Personne("Jean","Dupont",30) mais n'est pas l'objet lui-même. En C, on dirait que c'est un pointeur, c.a.d. l'adresse
de l'objet créé. Si on écrit ensuite :
p1=null;
Ce   n'est   pas   l'objet  Personne("Jean","Dupont",30)  qui   est   modifié,   c'est   la   référence  p1  qui   change   de   valeur.   L'objet
Personne("Jean","Dupont",30) sera "perdu" s'il n'est référencé par aucune autre variable.
Lorsqu'on écrit :
Personne p2=p1;
on initialise le pointeur p2 : il "pointe" sur le même objet (il désigne le même objet) que le pointeur p1. Ainsi si on modifie l'objet
"pointé" (ou référencé) par p1, on modifie aussi celui référencé par p2.
Lorsqu'on écrit :
Personne p3=new Personne(p1);
il y a création d'un nouvel objet Personne. Ce nouvel objet sera référencé par p3. Si on modifie l'objet "pointé" (ou référencé) par p1,
on ne modifie en rien celui référencé par p3. C'est ce que montrent les résultats obtenus.

 2.1.11 Passage de paramètres de type référence d'objet
Dans le chapitre précédent, nous avons étudié les modes de passage des paramètres d'une fonction lorsque ceux-ci représentaient
un type C# simple représenté par une structure .NET. Voyons ce qui se passe lorsque la paramètre est une référence d'objet :
1. using System;
2. using System.Text;
3.
4. namespace Chap1 {
5. class P12 {
6. public static void Main() {
7. // exemple 4
8. StringBuilder sb0 = new StringBuilder("essai0"), sb1 = new StringBuilder("essai1"), sb2 =
new StringBuilder("essai2"), sb3;
9. Console.WriteLine("Dans fonction appelante avant appel : sb0={0}, sb1={1}, sb2={2}",
sb0,sb1, sb2);
10. ChangeStringBuilder(sb0, sb1, ref sb2, out sb3);
11. Console.WriteLine("Dans fonction appelante après appel : sb0={0}, sb1={1}, sb2={2},
sb3={3}", sb0, sb1, sb2, sb3);
12.
13. }
14.
15. private static void ChangeStringBuilder(StringBuilder sbf0, StringBuilder sbf1, ref
StringBuilder sbf2, out StringBuilder sbf3) {
16. Console.WriteLine("Début fonction appelée : sbf0={0}, sbf1={1}, sbf2={2}", sbf0,sbf1,
sbf2);
17. sbf0.Append("*****");
18. sbf1 = new StringBuilder("essai1*****");
19. sbf2 = new StringBuilder("essai2*****");
20. sbf3 = new StringBuilder("essai3*****");
21. Console.WriteLine("Fin fonction appelée : sbf0={0}, sbf1={1}, sbf2={2}, sbf3={3}", sbf0,
sbf1, sbf2, sbf3);
22. }
23. }
24.}
• ligne 8 : définit 3 objets de type StringBuilder. Un objet StringBuilder est proche d'un objet string. Lorsqu'on manipule un
objet string, on obtient en retour un nouvel objet string. Ainsi dans la séquence de code :
1. string s="une chaîne";
2. s=s.ToUpperCase();
La ligne 1 crée un objet string en mémoire et s est son adresse. Ligne 2, s.ToUpperCase() crée un autre objet string en mémoire. Ainsi
entre les lignes 1 et 2, s a changé de valeur (il pointe sur le nouvel objet). La classe StringBuilder elle, permet de transformer une
chaîne sans qu'un second objet soit créé. C'est l'exemple donné plus haut :
• ligne 8 : 4 références [sb0, sb1, sb2, sb3] à des objets de type StringBuilder
• ligne 10 : sont passées à la méthode ChangeStringBuilder avec des modes différents : sb0, sb1 avec le mode par défaut, sb2
avec le mot clé ref, sb3 avec le mot clé out.
• lignes 15-22 : une méthode qui a les paramètres formels [sbf0, sbf1, sbf2, sbf3]. Les relations entre paramètres formels
formels sbfi et effectifs sbi sont les suivantes :
• sbf0 et sb0 sont, au démarrage de la méthode, deux références distinctes qui pointent sur le même objet (passage
par valeur des adresses)
• idem pour sbf1 et sb1
• sbf2 et sb2 sont, au démarrage de la méthode, une même référence sur le même objet (mot clé ref)
• sbf3 et sb3 sont, après exécution de la méthode, une même référence sur le même objet (mot clé out)
Les résultats obtenus sont les suivants :
1. Dans fonction appelante avant appel : sb0=essai0, sb1=essai1, sb2=essai2
2. Début fonction appelée : sbf0=essai0, sbf1=essai1, sbf2=essai2
3. Fin fonction appelée : sbf0=essai0*****, sbf1=essai1*****, sbf2=essai2*****, sbf3=essai3*****
4. Dans fonction appelante après appel : sb0=essai0*****, sb1=essai1, sb2=essai2*****,
sb3=essai3*****
Explications :
• sb0 et sbf0 sont deux références distinctes sur le même objet. Celui-ci a été modifié via sbf0 - ligne 3. Cette modification
peut être vue via sb0 - ligne 4.

• sb1  et  sbf1  sont deux références distinctes sur le même objet.  sbf1  voit sa valeur modifiée dans la méthode et pointe
désormais sur un nouvel objet - ligne 3. Cela ne change en rien la valeur de sb1 qui continue à pointer sur le même objet -
ligne 4.
• sb2 et sbf2 sont une même référence sur le même objet. sbf2 voit sa valeur modifiée dans la méthode et pointe désormais
sur un nouvel objet - ligne 3. Comme sbf2 et sb2 sont une seule et même entité, la valeur de sb2 a été également modifiée et
sb2 pointe sur le même objet que sbf2 - lignes 3 et 4.
• avant appel de la méthode, sb3 n'avait pas de valeur. Après la méthode, sb3 reçoit la valeur de sbf3. On a donc deux
références sur le même objet - lignes 3 et 4

2.1.12 Les objets temporaires
Dans une expression, on peut faire appel explicitement au constructeur d'un objet : celui-ci est construit, mais nous n'y avons pas
accès (pour le modifier par exemple). Cet objet temporaire est construit pour les besoins d'évaluation de l'expression puis
abandonné. L'espace mémoire qu'il occupait sera automatiquement récupéré ultérieurement par un programme appelé "ramasse-
miettes" dont le rôle est de récupérer l'espace mémoire occupé par des objets qui ne sont plus référencés par des données du
programme.
Considérons le nouveau programme de test suivant :
1. using System;
2.
3. namespace Chap2 {
4. class Program {
5. static void Main() {
6. new Personne(new Personne("Jean", "Dupont", 30)).Identifie();
7. }
8. }
9. }
et modifions les constructeurs de la classe Personne afin qu'ils affichent un message :
1. // constructeurs
2. public Personne(String p, String n, int age) {
3. Console.WriteLine("Constructeur Personne(string, string, int)");
4. Initialise(p, n, age);
5. }
6. public Personne(Personne P) {
7. Console.Out.WriteLine("Constructeur Personne(Personne)");
8. Initialise(P);
9. }
Nous obtenons les résultats suivants :
1. Constructeur Personne(string, string, int)
2. Constructeur Personne(Personne)
3. [Jean, Dupont, 30]
montrant la construction successive des deux objets temporaires.

Publié par Drupal french Study