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

Lazarus Pascal Discussion :

Stack overflow lors du changement d'une propriété d'une classe personnalisée [Lazarus]


Sujet :

Lazarus Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Avatar de nouanda
    Homme Profil pro
    Hobbyist
    Inscrit en
    Mai 2002
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Australie

    Informations professionnelles :
    Activité : Hobbyist

    Informations forums :
    Inscription : Mai 2002
    Messages : 246
    Par défaut Stack overflow lors du changement d'une propriété d'une classe personnalisée
    Bonjour à tous,

    A des fins de formation totalement personnelle, je m’entraîne a créer une classe pour manipuler des dates.
    Je ne la dérive pas de TDate ou TDateTime, c'est simplement un objet.
    Il y a une procédure pour lui attribuer une date qui sert de base, et a partir de la, j'essaie de récupérer jour mois année, etc... Bref, un petit exercice pour me familiariser avec le classes.
    J'arrive sans problème à récupérer les propriétés, avec des getters, mais lorsque j'essaie de changer une propriété, j'obtiens des stackoverflow.
    par exemple, le code ci-dessous:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    type
      TCustomDate = class
        private
          WorkingDate : TDate;
          function GetMonth     : word;
          procedure SetMonth(Value: word);
        published
          property Month     : word   read GetMonth write SetMonth;
    avec le getter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function TCustomDate.GetMonth : word;
      begin
        GetMonth := myMonth ;
      end;
    et le setter

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TCustomDate.SetMonth(Value: word) ;
      begin
        Month := Value ;
      end;
    Donc la propriété Month obtient très bien la valeur myMonth (initialisée par ailleurs), mais si je veux changer cette propriété (par exemple myObject.Month:=myObject.Month-1), j'obtiens un stackoverflow, et je ne comprends pas pourquoi.
    Pouvez-vous m'éclairer, je vous en prie?

    Lazarus 1.0.10 win32

  2. #2
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 942
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 942
    Billets dans le blog
    6
    Par défaut
    Ceci s'explique bien par la ligne Month := Value; qui fait appel à SetMonth pour changer la valeur, etc.
    Ce pourquoi il faudrait la transformer en myMonth := Value;, pour peu que myMonth soit bien un champ (privé de préférence) de ta classe, qui gagnerait donc à s'appeler FMonth avec le F comme Field (champ). Par 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
    type
      TCustomDate = class
        private
          FMonth     : word;
          procedure SetMonth(AValue: word);
        published
          property Month     : word   read FMonth write SetMonth; // pas besoin de GetMonth s'il ne fait que lire le champ privé
      end;
     
    procedure TCustomDate.SetMonth(AValue: word) ;
      begin
        if Value in [1..12] 
        then FMonth := AValue // AValue avec le A comme Argument
        else raise Exception.Create('Saisir un mois entre 1 et 12');
      end;
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  3. #3
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 786
    Par défaut
    Bonjour,
    1. J'ai regardé le code donné en exemple, mais je ne vois pas de variable privée correspondant aux accesseurs (getter et setter),
    2. published est utilisée pour des propriétés modifiables depuis le concepteur visuel de l'EDI, sinon public est plus appropriée.

    Le code remanié :
    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
    type
      TCustomDate = class
      private
        myMonth: word;
        function GetMonth: word;
        procedure SetMonth(Value: word);
      //published
      public
        property Month: word read GetMonth write SetMonth; 
      end;
    // ...
    function TCustomDate.GetMonth: word;
    begin
      GetMonth := myMonth;
    end;
     
    procedure TCustomDate.SetMonth(Value: word);
    begin
      myMonth := Value;
    end;
    Citation Envoyé par nouanda Voir le message
    Donc la propriété Month obtient très bien la valeur myMonth (initialisée par ailleurs), mais si je veux changer cette propriété (par exemple myObject.Month:=myObject.Month-1), j'obtiens un stackoverflow, et je ne comprends pas pourquoi.
    Pouvez-vous m'éclairer, je vous en prie?

    Lazarus 1.0.10 win32
    Un débordement de pile ?
    Avez vous essayé de tracer l'appel pas à pas pour voir quelle ligne de code précise déclenche l'erreur ?
    @tourlourou a été plus attentif que moi 1 . Le problème vient du setter appelé récursivement...

  4. #4
    Membre chevronné
    Avatar de nouanda
    Homme Profil pro
    Hobbyist
    Inscrit en
    Mai 2002
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Australie

    Informations professionnelles :
    Activité : Hobbyist

    Informations forums :
    Inscription : Mai 2002
    Messages : 246
    Par défaut
    Bonjour,

    Je vous remercie de vos réponses. Grâce à elles, je progresse dans la compréhension des classes en pascal objet.
    En effet, les tutoriels que j'ai trouvé sur le net ne sont pas toujours très clairs, et je pensais que comme en java, un setter devait modifier directement la propriété (d'ou le Month := Value ; ).
    Merci pour la précision public/published également.
    Problème résolu!

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 14/12/2013, 01h05
  2. Réponses: 10
    Dernier message: 23/03/2011, 17h10
  3. Réponses: 10
    Dernier message: 01/12/2010, 09h26
  4. Binding sur une proprité d'une propriété
    Par al2000 dans le forum Windows Forms
    Réponses: 0
    Dernier message: 21/06/2010, 18h24
  5. Recherche une valeur d'une cellule dans une colonne d'une autre feuille
    Par kourria dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 21/06/2007, 14h48

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