|
Site |
Cours VB.net |
|
|
|
Les variables par valeur ou par référence. |
|
|
Résumons la notion très importante de variable par valeur ou par référence.
Un type de données est un type valeur s'il contient des données dans l'espace qui lui est alloué en mémoire. Un type référence contient un pointeur vers un autre emplacement en mémoire contenant les données.(dixit MicroSoft)
La variable 'par Valeur':
Contient réellement une valeur.
Prenons pour exemple une variable de type 'Long'
Dim L As Long
L= 1456
L occupe 8 octets nécessaire pour coder un long, ici L a une valeur de 1456, donc dans ces 8 octets il est codé 1456.
Quels sont les types de variables par 'Valeur'?
Les Integer, les Long les Short
Les Single, Double, Decimal
Les Booleans, Char, Date
Les Structures
Les énumérations
La variable 'par Référence':
Elles ne contiennent pas la valeur de l'objet mais son adresse en mémoire, sa référence.
Dim O As Object
O contient l'adresse de l'objet codée sur 4 octets.
Quels sont les types de variables par référence:
Les Objets
Les Strings
Les tableaux
Les Classes
Influence sur l'Affectation:
Posons le problème:
Travaillons sur A et B, 2 variables ayant la même 'nature'.
Dim A As ...
A existe donc, faisons:
Dim B=A
Puis modifions la valeur de A, cela modifie t-il B?
Les variables par Valeur ou par Référence ne réagissent pas de la même manière:
Si le type de variable est par valeur (valable pour les entiers, les Long.. les structures..), chaque variable ayant sa valeur, B n'est pas modifié.
Si le type de variable est par référence (valable pour les tableaux, les objets, les string..), chaque variable est définie par sa référence (son lieu physique); faire A=B entraîne que A et B ont même référence. Si on modifie A, B est modifié car il pointe au même endroit.
Voyons des exemples:
Même si on affecte une variable par valeur à une autre, les deux variables restent différentes: elles conservent leur propre espace de stockage:
Dim L As Long
Dim P As Long
L=0
L=P 'on affecte P à L
P=4 'on modifie P
=> L=0 P=4 Modifier P n'a pas modifié L
Par contre si on affecte une variable par référence à une autre, elle pointe toutes les 2 sur le même endroit mémoire: si j'en modifie une, cela modifie l'autre.
Créons une Classe contenant un entier (Exemple à relire quand vous aurez étudié les Classes)
Class Class1
Public Value As Integer = 0
End Class
Dim C1 As New Class1()
Dim C2 As Class1 =C1 'on
crée C2, on affecte C1 à C2
C2.Value = 123 'on modifie C2
=> C1.Value=123 C2.Value=123 Modifier
C2 a modifié C1 car elles pointent sur le même endroit mémoire.
On se méfiera donc du type 'référence ' ou 'Valeur' des données que l'on utilise: exemple des Tableaux
Exemple sur les tableaux qui sont 'Par référence':
Dim
A(3) As StringA(1) = "a"
Dim B(3) As StringB(1) = "b"
B = A
A(1) = "c"
Label1.Text() = B(1) 'Affiche 'c'
En effet un tableau est 'par référence' et le fait de faire A=B donne la même adresse mémoire aux 2 tableaux, aussi , modifier l'un modifie l'autre.
B= A.Clone aurait copié le tableau A dans B en conservant 2 tableaux distinct et la dernière instruction aurait affiché 'a'.
Remarque: A(2)=B(2) affecte un élément d'un tableau à un élément d'un autre tableau, cela ne modifie que la valeur d'un élément et n'affecte pas le tableau.
Le cas particulier des 'String' qui sont 'Par référence':
Attention: par contre :
Dim
A As StringA = "a"
Dim B As StringB = "b"
B = A
A = "c"
Label1.Text() = B 'Affiche 'a'
Bien que cela soit par référence, B=A affecte simplement la valeur de A à B, si on modifie ultérieurement A, B n'est pas modifié. (idem pour clone et copy!!) Pour une string qui est 'par référence', il parait donc impossible de la dupliquer, elle se comporte comme une variable par valeur!! Avez -vous des idées pour expliquer cela?
L'opérateur d'affectation "=" de deux strings "A=B" a simplement étédéfini de manière restrictive pour les strings. Les créateurs de vb .netlui ont permis uniquement une copie de la valeur de la string et non de la référence.Il vaut mieux ne pas permettre l' affectation de la même référence pointant sur le mêmeobjet c'est dangereux pour les débutants et cela serait totalement incompatible avec les versions précédentes..Ensuite, parce que la copie de la valeur d'une string dans une autre estune opération extrêmement courante chez les programmeurs. Ce qui n'estpas le cas de l'affectation de la même référence pointant sur le mêmeobjet.En conclusion, rien de choquant dans le fait qu'un type string se comportecomme un type par valeur: car c'est juste la définition de l'opérateurd'affectation "=" qui a été redéfinie, et c'est tout. Tout ce qui concernel'implémentation du type string est strictement comme tous les typespar référence. (Merci Sabri)
Déclaration avec New ?
En théorie, il faut utiliser New quand on déclare une variable 'par référence':
Il faut écrire:
Dim L As Long 'un long est 'par valeur'
Dim F As New Button 'un bouton est un objet 'par référence'
En fait
Dim L As New Long 'est accepté
Dim O As Object 'est accepté mais il faudra redéfinir O avec New pour l'utiliser.
Dim S As String 'est accepté.
Pour les Classes ou les objets graphiques , il faut par contre bien taper New pour créer l'objet:
Dim F As New Button
Si on tape Dim F As Button on crée une référence vide, mais pas d'objet Button.
Valeur après déclaration:
Après création (avant initialisation) une variable numérique 'par Valeur' contient 0,
Dim L As Long 'L contient 0
Par contre une String (par référence) qui a été créée par Dim et non initialisée contient Nothing.
Dim O As Object 'O contient Nothing: il ne pointe sur aucun objet.
On peut le tester par If IsNothing( O ) then.. ou If O Is Nothing..
Pour les tableaux, bien que le tableau soit 'par Référence', c'est le type de variable utilisée dans le tableau qui décide de la valeur des éléments après déclaration.
Dim T(3) As Long '=>T(0)=0
Comparaison:
1-Une variable par Valeur peut être comparée à une autre par "=",
Dim L As Long=12
Dim P As Long=24
If L=P Then..
2-Par contre une variable par référence peut être comparée à une autre par "Is".
Dim O As Object
Dim Q As Object
If O Is Q then..
NB: pour les String '=' et 'Is' peuvent être utilisés.
3-Equals peut être utilisé pour comparer les 2 types de données:
Obj1.Equals(Obj2))
'Retourne True si Obj1 et Obj2 ont le même pointeur.
ou
N1.Equals(N2)
'Retourne True si la valeur de N1= la valeur de N2
Pour les types référence, l'égalité est définie comme une égalité d'objets, c'est-à-dire si les références renvoient ou non au même objet. Pour les types valeur, l'égalité est définie comme une égalité au niveau du bit de la valeur.
Il existe une instruction permettant de voir si une variable est de type 'Par référence'
Cet exemple utilise la fonction IsReference
(Microsoft.VisualBasic.Information.IsReference)
pour vérifier si plusieurs variables font référence à des types référence.
Dim R as Boolean
Dim MyArray(3) As Boolean
Dim MyString As String
Dim MyObject As Object
Dim MyNumber As Integer
R = IsReference(MyArray)
' R= True. Tableau
R = IsReference(MyString) ' R= True. String
R = IsReference(MyObject) ' R= True. Objet
R = IsReference(MyNumber) ' R= False. Entier
|
|
|
|
|