IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Pourquoi ma FUNCTION change la valeur de la variable passée ? référence / valeur


Sujet :

VB.NET

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 62
    Points : 43
    Points
    43
    Par défaut Pourquoi ma FUNCTION change la valeur de la variable passée ? référence / valeur
    Bonjour à tous et merci du temps que je vous prends,

    j'apprends le VB.NET et je bute depuis plusieurs jours sur le problème suivant :
    j'ai une variable nommée departure, elle même ayant la structure de la classe CoordGPS définie ainsi :

    classe.vb
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Public Class CoordGPS
        Public Lat As Double
        Public Lon As Double
    End Class
    Quand je clique sur le bouton OK de ma form, le code est censé envoyer la variable departure à la fonction essai_func. Celle-ci utilise une variable intermédiaire nommée abc et est convertie par la fonction DR( ), qui elle-même utilise une variable interne nommée deg (de structure CoordGPS).

    Mais a priori, je pensais (et j'aimerais obtenir) que departure ne soit pas elle-même modifiée ! ! ! pourtant c'est ce qui se passe dans le code suivant :

    Form1.vb

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    Public Class Form1
        Dim Departure As New CoordGPS
     
    '_____________________________________________
     
        Public Function DR(ByVal deg As Object) As Object
     
            If deg.GetType.Name = "CoordGPS" Then
                deg.Lat = deg.Lat * 2
                deg.Lon = deg.Lon * 2
            ElseIf deg.GetType.Name = "Double" Then
                deg = deg * 2
            End If
            Return deg
        End Function
     
    '____________________________________________
     
        Public Function essai_func( _
                ByVal dep As CoordGPS _
                ) As Double
            Dim res As Double
            Dim abc As New CoordGPS
     
            MsgBox("1: " & dep.Lat & " / " & dep.Lon)
            abc = DR(dep)
            MsgBox("2: " & dep.Lat & " / " & dep.Lon)
            res = abc.Lat
            Return res
        End Function
     
    '____________________________________________
     
        Private Sub ok_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ok.Click
            Departure.Lat = 10
            Departure.Lon = 1
     
            Label1.Text = essai_func(Departure).ToString
            Label2.Text = Departure.Lat & " : " & Departure.Lon
     
        End Sub
     
    End Class
    je ne comprends pas pourquoi le msgbox n°2 renvoie la valeur de dep.Lat et dep.Lon 20 : 1 alors que dep n'a a priori pas été modifiée !, idem dans l'évênement OK_clickdeparture ne devrait pas être modifiée et devrait renvoyer les valeurs d'origine à savoir 10 : 1

    Si quelqu'un a la clé de mon problème, merci de m'aider, je n'y comprends plus rien !!!

    ps : j'ai affiché ici une version très simplifiée de mon code, pour comprendre ce qui ne va pas, ce que j'ai mal assimilé. Je ne cherche pas une réécriture plus compacte car j'ai besoin de ces différentes fonctions dans mon vrai projet, mais je ne souhaite pas embeter tout le monde avec autant de lignes de code pour pas grand chose. La source est dans le zip joint ci-dessous.
    Fichiers attachés Fichiers attachés

  2. #2
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    simplement car c'est une classe.
    Les classe sont des références aux objets. Modifier un champ dans une classe revient donc à modifier la référence, qui pointes donc vers l'objet original.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Public Class CoordGPS Public Lat As Double  Public Lon As Double End Class
    pour te simplifier la vie, utilise des Struct au lieu de classes car les Structures sont passé en valeur et non pas en référence
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Public Struct CoordGPS Public Lat As Double  Public Lon As Double End Class
    Je pense que tu devrais consacrer un peut de temps à lire la documentation ou des tutoriels .NET sur la notion de Class et Struct

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 62
    Points : 43
    Points
    43
    Par défaut
    merci de ta réponse si rapide. Je passe mes nuits à lire le Cours VB.NET par Philippe Lasserre. Visiblement je ne lis aps assez bien , mais c'est un peu nouveau pour moi.

    J'ai besoin d'une classe car je veux rajouter à CoordGPS des évênements, des fonctions, un tas de choses pour proposer une classe prête à l'emploi une fois que j'aurai rédigé mon projet, qui pourra éventuellement servir à d'autres dans la destion d'un GPS sur port série, calculs de distance, d'orthodromie etc.

    Je pensais qu'une classe était un cadre général et que parmi les classes on pouvait définir plusieurs objets qui avaient la structure de la classe les propriétés de celle-ci, les fonctions de celle-ci, mais pas que tout le monde avait la même valeur ! Je n'y comprends décidément plus rien après ton message.

    Je pensais qu'on définissait des objets MaVariable_x de la manière suivante :
    Dim MaVariable_1 as New CoordGPS
    Dim MaVariable_2 as New CoordGPS

    et que dans chaque MaVariable_n on retrouvait les mêmes "extensions" (le truc après le point) comme par exemple :
    MaVariable_1.Lat = 49.5
    et
    MaVariable_2.Lat = 60

    et surtout j'avais cru comprendre que dans ce cas MaVariable_1.Lat gardait sa valeur 49.5, et tu me dis qu'en fait c'est CoordGPS.Lat qui prend la valeur 60 et donc MaVariable_1.Lat s'en trouve modifée ???


    Merci d'un peu d'éclairage, j'ai peur de faire fausse route en te lisant et la plupart de mes certitudes acquises ces derniers jours sont entrain de s'évanouir dans les méandres de la programmation objet. Elles hululent à la nuit tombée ....

    Plus sérieusement, je pensais que la source de mon problème était une erreur de déclaration de mes variables me mélangeant les pédales entre PUBLIC, PRIVATE etc.

    Merci

  4. #4
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    google est ton ami ...
    http://www.google.fr/search?hl=fr&rl...chercher&meta=

    en gros voilà :
    - Pour une struct

    Lors du passage d'une struct en paramètre, la valeur de la structure est copiée dans la fonction et on travail donc sur la copie de cet objet dans le code.

    - Pour une class

    Un réference ( un pointeur ) est passé à la fonction et exécuter n'importe quel type d'action sur la class revient à appeller l'action sur le pointeur, donc l'action s'exécute en réalité sur l'objet d'origine car les classes ne sont pas copiées, mais référencées.
    Le comportement d'une classe ressemble à une struct passé avec le mot clef ref en C# ( je crois que c'est ByRef en VB ).

    Je ne comprend pas trop ton code mais c'est ainsi que fonctionne les Class et Struct en .NET ( d'ailleurs en C++ les classes correspondent aux pointers ).

    Ensuite, si tu veux absolument pouvoir modifier une classe sans modifier l'originale, il faudra que tu fasses une copie de la classe avant de la modifier.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 62
    Points : 43
    Points
    43
    Par défaut
    merci merci merci et quadruple merci

    Je n'aurais jamais trouvé cela tout seul, cela dépassait largement le cadre de références que j'ai dans la programmation objet et plus particulièrement VB.NET (je ne connais ni C++ ni C# ni...)

    j'ai trouvé ce post qui traîte de cela en référence à VB6 grâce à ton ami Google qui devient le mien, mais pas trop fidèle pour le moment, un peu trop volage et imaginatif, pas assez ciblé, de toute manière les mots référence et valeur restaient pour moi du pur ésotérisme avant ton intervention.

    Je vais chercher une solution comme proposé, mais ai-je tord de dire qu'imaginer que pouvoir passer les classes par valeur serait tout de même une bonne chose plutôt que par référence ? Surtout que dans mon code j'ai écrit
    Public Function DR(ByVal deg As CoordGPS) As CoordGPS
    et idem pour l'autre fonction ...

    Merci encore pour ta réponse

    edit : l'explication de mon problème est ici et je l'avais loupée ! : http://plasserre.developpez.com/v1-6val.htm
    d'autres explications dans cette discussion :
    http://www.developpez.net/forums/arc.../t-119757.html

  6. #6
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    N'oublit pas la balise si on a répondu à tes questions

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 62
    Points : 43
    Points
    43
    Par défaut
    désolé, c'est réparé.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 15
    Dernier message: 13/02/2015, 16h24
  2. Réponses: 4
    Dernier message: 10/03/2014, 21h54
  3. Réponses: 6
    Dernier message: 18/01/2007, 10h24
  4. Pourquoi ma variable perd sa valeur ?
    Par Bruno29 dans le forum Flash
    Réponses: 10
    Dernier message: 17/01/2007, 20h56
  5. Réponses: 2
    Dernier message: 04/01/2007, 13h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo