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

Langage Delphi Discussion :

Initialisation des variables d'un record pas toujour identique !


Sujet :

Langage Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2002
    Messages : 84
    Points : 57
    Points
    57
    Par défaut Initialisation des variables d'un record pas toujour identique !
    Bonjour,
    J'ai un souci avec un record lequel, après avoir fait le "New()", me retourne l'une de ses valeurs une fois "true" et une fois "false" !
    Je m'explique, mon record est déclaré comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    TXxxMyRecord = record
      ReadOnly: Boolean; 
    end;
    pXxxmyRecord = ^TXxxMyRecord;
    Ensuite, j'utilise mon record comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    ...
    var
      pCallXxxmyRecord : pXxxmyRecord ;
    begin
      New(pCallXxxmyRecord);
      ShowMessage('Read Only = ' + BoolToStr(pCallXxxmyRecord^.ReadOnly, true));
    ...
    Et bien là, une fois sur deux, la valeur est "true" alors qu'elle devrait être tout le temps "false" !

    Une idée ... je sèche ... merci d'avance.

  2. #2
    Membre actif

    Homme Profil pro
    Inscrit en
    Mars 2009
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2009
    Messages : 128
    Points : 203
    Points
    203
    Par défaut
    Bonjour

    Le New renvoie une adresse en Ram et y alloue la place nécessaire pour l'enregistrement. Cela ne veut pas dire que les variables y soient initialisées. Donc à mon avis il manque :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pCallXxxmyRecord^.ReadOnly := false;
    aussitôt après l'appel du new...

    ... Et pourquoi ne pas faire de ce TRecord un TObjet avec une méthode create qui initialiserait les variables ?

  3. #3
    Membre chevronné

    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2009
    Messages
    935
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2009
    Messages : 935
    Points : 1 765
    Points
    1 765
    Par défaut
    Salut

    Il me semble que c'est normal : New alloue simplement la mémoire nécéssaire. Une initialisation de la variable est quand même nécéssaire.

    Si tu veux initialiser ta variable à false, tu fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pCallXxxmyRecord^.ReadOnly := false
    Edit : Trop tard

  4. #4
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    quand je crée un enregistrement je déclare systématiquement deux constantes dans la plupart des cas (quand l'enregistrement necessite des valeurs par défaut) :

    comme suis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    type
      P[id] = ^T[id];
      T[id] = record
        [fields: type]
      end;
     
      const
        SizeOf[id] = SizeOf(T[id]);
        [id]Default : T[id] = (
          [fields: defaultValue,]
        );

    exemple :

    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
     
    type
      PRBoolean = ^TRBoolean;
      TRBoolean = record
        Value : boolean;
      end;
     
      const
        SizeOfRBoolean = SizeOf(TRBoolean);
        RBooleanDefault : TRBoolean = (
          Value : false
        );
     
      function NewRBoolean: PRBoolean;
      begin
        New(result);
        result := RBooleanDefault;
      end;
    et sous Delphi 2007+

    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
    44
    45
    46
    47
    48
    49
    50
    51
     
    type
      PRBoolean = ^TRBoolean;
      TRBoolean = record
        Value: Boolean;
        class function New: PRBoolean; static;
        class function Init: TRBoolean; static;
        procedure Reinit;
      end;
      const
        SizeOfRBoolean = SizeOf(TRBoolean);
        RBooleanDefault : TRBoolean = (
          Value : false
        );
     
    class function TRBoolean.New: PRBoolean;
    begin
      new(result);
      result := RBooleanDefault;
    end;
     
    class function TRBoolean.Init: TRBoolean;
    begin
      result := RBooleanDefault;
    end;
     
    procedure TRBoolean.Reinit;
    begin
      Value := RBooleanDefault.Value;
    end;
     
     
    // exemple :
    var
      MainTRB : TRBoolean = RBooleanDefault;
     
    procedure ....;
    var PRB : PRBoolean;
         TRB : TRBoolean;
    begin
      PRB := TRBoolean.New;
      TRB := TRBoolean.Init;
     
      TRB.Value := MainTRB.Value;
     
      PRB^ := TRB;
     
      TRB.Reinit;
     
      Dispose(PRB);
    end;
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  5. #5
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 771
    Points
    2 771
    Par défaut
    Citation Envoyé par Rekin85 Voir le message
    Bonjour
    Le New renvoie une adresse en Ram et y alloue la place nécessaire pour l'enregistrement. Cela ne veut pas dire que les variables y soient initialisées.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    pXxxmyRecord = ^TXxxMyRecord;
    TXxxMyRecord = record
      ReadOnly: Boolean; 
    end;
    ...
    var
      pCallXxxmyRecord : pXxxmyRecord ;
    begin
      New(pCallXxxmyRecord);
      fillchar(pCallXxxmyRecord^,sizeof(TXxxMyRecord),0);// bien sur si ton record à plus d'un champ, pas comme ici 
      ShowMessage('Read Only = ' + BoolToStr(pCallXxxmyRecord.ReadOnly, true));
    PAS DE DESTIN, C'EST CE QUE NOUS FAISONS

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2002
    Messages : 84
    Points : 57
    Points
    57
    Par défaut Diverses solutions d'initialisation des champs des records
    Merci à tous pour votre contribution. Voici ci-dessous un exemple complet dans une forme.

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
     
    unit FormTest;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
     
    type
     
      ThciFormTest = class(TForm)
        hciButtonVersion1: TButton;
        hciButtonVersion2: TButton;
        hciButtonVersion3: TButton;
        procedure hciButtonVersion1Click(Sender: TObject);
        procedure hciButtonVersion2Click(Sender: TObject);
        procedure hciButtonVersion3Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
     
      // --- Version 1 ---
      PRMyRecord1 = ^TRMyRecord1;
      TRMyRecord1 = record
        ReadOnly : Boolean;
        Enabled  : Boolean;
        { CE QUI SUIT EST IMPORTANT : "class procedure" }
        class procedure New(var pv_PRMyRecord1 : PRMyRecord1); static;
      end;
      // ------
     
     
      // --- Version 2 ---
      PRMyRecord2 = ^TRMyRecord2;
      TRMyRecord2 = record
        ReadOnly : Boolean;
        Enabled  : Boolean;
        { CE QUI SUIT EST IMPORTANT : "constructor" }
        constructor New(var pv_PRMyRecord2 : PRMyRecord2);
      end;
      // ------
     
     
      // --- Version 3 ---
      PRMyRecord3 = ^TRMyRecord3;
      TRMyRecord3 = record
        ReadOnly : Boolean;
        Enabled  : Boolean;
      end;
      { CE QUI SUIT EST IMPORTANT : "InitializedTRMyRecord3" }
      const
        InitializedTRMyRecord3 : TRMyRecord3 = (ReadOnly : True; Enabled : False);
      // ------
     
     
     
    var
      hciFormTest: ThciFormTest;
     
     
     
    implementation
     
    {$R *.dfm}
     
     
     
     
    // --- Version 1 ---
    class procedure TRMyRecord1.New(var pv_PRMyRecord1 : PRMyRecord1);
    begin
      // il faut préfixer le "New" par "System" afin que le compilateur n'appelle pas
      // la fonction "New" ici présente ... et dise qu'il y a trop de paramètres ...
      System.New(pv_PRMyRecord1);
      // Initialisation des champs du record
      pv_PRMyRecord1.ReadOnly := true;
      pv_PRMyRecord1.Enabled  := false;
    end;
     
    // --- Version 1 ---
    procedure ThciFormTest.hciButtonVersion1Click(Sender: TObject);
    var
      ptrPRMyRecord1 : PRMyRecord1;
    begin
      TRMyRecord1.New(ptrPRMyRecord1); // IL FAUDRAIT AJOUTER "TRMyRecord1." devant tous les appels à "New" dans le code existant
      ShowMessage('ptrPRMyRecord.ReadOnly = ' + BoolToStr(ptrPRMyRecord1.ReadOnly, true) + #13#10 +
                  'ptrPRMyRecord.Enabled  = ' + BoolToStr(ptrPRMyRecord1.Enabled, true));
    end;
     
     
     
     
    // --- Version 2 ---
    constructor TRMyRecord2.New(var pv_PRMyRecord2 : PRMyRecord2);
    begin
      // il faut préfixer le "New" par "System" afin que le compilateur n'appelle pas
      // la fonction "New" ici présente ... et dise qu'il y a trop de paramètres ...
      System.New(pv_PRMyRecord2);
      // Initialisation des champs du record
      pv_PRMyRecord2.ReadOnly := true;
      pv_PRMyRecord2.Enabled  := false;
    end; 
     
    // --- Version 2 ---
    procedure ThciFormTest.hciButtonVersion2Click(Sender: TObject);
    var
      ptrPRMyRecord2 : PRMyRecord2;
    begin
      TRMyRecord2.New(ptrPRMyRecord2); // IL FAUDRAIT AJOUTER "TRMyRecord2." devant tous les appels à "New" dans le code existant
      ShowMessage('ptrPRMyRecord.ReadOnly = ' + BoolToStr(ptrPRMyRecord2.ReadOnly, true) + #13#10 +
                  'ptrPRMyRecord.Enabled  = ' + BoolToStr(ptrPRMyRecord2.Enabled, true));
    end;
     
     
     
    // --- Version 3 ---
    procedure ThciFormTest.hciButtonVersion3Click(Sender: TObject);
    var
      RMyRecord3 : TRMyRecord3;
    begin
      RMyRecord3 := InitializedTRMyRecord3; // Là on a un record directement initialisé, mais pas de pointeur !
      ShowMessage('RMyRecord3.ReadOnly = ' + BoolToStr(RMyRecord3.ReadOnly, true) + #13#10 +
                  'RMyRecord3.Enabled  = ' + BoolToStr(RMyRecord3.Enabled, true));
    end;
     
    end.

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

Discussions similaires

  1. Initialisation des variables globales dans un package
    Par fred_hte_savoie dans le forum SQL
    Réponses: 2
    Dernier message: 17/04/2007, 10h26
  2. Réponses: 6
    Dernier message: 14/03/2007, 22h04
  3. Réponses: 13
    Dernier message: 05/11/2006, 22h53
  4. Initialisation des variables
    Par gagarine dans le forum Langage
    Réponses: 3
    Dernier message: 03/08/2006, 11h36
  5. [débutant] initialisation des variables.
    Par zui dans le forum Langage
    Réponses: 1
    Dernier message: 05/06/2006, 15h29

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