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 :

[Exemple du site] Redéfinition de méthode : appel de l'ancêtre erroné ?


Sujet :

Langage Delphi

  1. #1
    Membre actif
    Homme Profil pro
    Freelance
    Inscrit en
    Décembre 2003
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : Décembre 2003
    Messages : 423
    Points : 259
    Points
    259
    Par défaut [Exemple du site] Redéfinition de méthode : appel de l'ancêtre erroné ?
    Bonjour,


    Sur les pages persos de developpez on peut trouver le code suivant ici :
    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
    type
      TThreadedTimer = class(TThread)
      private
        FEvent : TEvent;  { Evènement interne }
        FInterval : Cardinal; { Intervalle }
        FOnTimer: TNotifyEvent;  { Procédure d'événement à appeller pour exécuter le code }
      protected
        procedure Execute; override;
        procedure DoTimer; { Wrapper pour FOnTimer }
      public
        constructor Create(ACreateSuspended : Boolean; AInterval : Cardinal);  { Constructeur }
        destructor Destroy; override; { Destructeur }
        procedure Terminate; reintroduce; { Procédure de terminaison à nous, redéfinie }
        property Terminated; { réexpose la propriété ancètre }
        property OnTimer : TNotifyEvent read FOnTimer write FOnTimer;  { Propriété 
    	   permettant la gestion de l'événement utilisateur FOnTimer }
      end;
    
    implementation
    
    constructor TThreadedTimer.Create(ACreateSuspended : Boolean; AInterval : Cardinal);
    begin
      FEvent := TEvent.Create(nil, False, False, ''); { Créer l'événement désactivé }
      FInterval := AInterval; { Mémoriser l'intervalle }
      inherited Create(ACreateSuspended); { Appeller la méthode ancètre }
    end;
    
    destructor TThreadedTimer.Destroy;
    begin
      FreeAndNil(FEvent); { Détruire l'événement }
      inherited;
    end;
    
    procedure TThreadedTimer.DoTimer;
    begin
      if Assigned(FOnTimer) then { procédure assignée ?... }
        FOnTimer(Self); { ... alors l'exécuter }
    end;
    
    procedure TThreadedTimer.Execute;
    begin
      while not Terminated do
      try
         case FEvent.WaitFor(FInterval) of
           wrSignaled : Terminate; { Evènement déclenché. Demande de fin de thread. On sort de la boucle }
           wrTimeout : DoTimer; { Délai atteint : on exécute la procédure }
         end;
      finally
      end;
    end;
    
    procedure TThreadedTimer.Terminate;
    begin
      FEvent.SetEvent; { Activer l'evénement }
    end;
    J'aimerai attirer votre attention sur ce que j'ai fait resortir en rouge :
    on redéfini ici la méthode Terminate qui, dans sa nouvelle implémentation en fait pas appel à Terminate de l'ancêtre. Jusque là pas de problème, sauf que dans la méthode execute du thread dès que l'évènement est signalé on fait appel à la méthode Terminate.
    Alors à moins que le mot clé reintroduce ait un autre effet que de masquer les messages du compilateur, pour moi ce code ne fonctionne pas car justement l'appel à Terminate dans le corps execute du thread rappel la méthode Terminate que l'on a défini nous et par conséquent on tourne en rond et on ne sort jamais ...


    Vrai ou grosse erreur de ma part ?



    Merci à quiconque pourra répondre

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    Citation Envoyé par Bleys
    l'appel à Terminate dans le corps execute du thread rappel la méthode Terminate que l'on a défini nous et par conséquent on tourne en rond et on ne sort jamais...
    C'est bien ce qui est codé ici.
    Vrai ou grosse erreur de ma part ?
    Je dis VRAI.

  3. #3
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Tu as tout à fait raison.

    Cette méthode n'aurait pas dû s'appeler Terminate. Elle aurait dû s'appeler Stop ou qqch comme ça, mais pas Terminate.

  4. #4
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    Faudrait au moins transformer comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Procedure TThreadedTimer.Terminate;
    Begin
      Inherited Terminate; { Appeller la méthode ancètre }
                           { Donc Met Terminated=True }
      FEvent.SetEvent; { Activer l'evénement }
                           { Donc n'execute pas DoTimer}
    End;
    je suis curieux d'avoir ton avis sjrd...

  5. #5
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    C'est effectivement le moins qu'on puisse faire. Mais ce n'est pas suffisant. Renommer la méthode serait mieux, car sinon :
    n'est pas équivalent à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var
      Thread: TThread;
     
    Thread := MonThread;
    Thread.Terminate;
    Ce qui est très dangereux, et pas du tout bon question méthode orientée objet.

  6. #6
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    ha oui! Maintenant je vois bien!

    Merci pour cet avis!
    sjr objet!

  7. #7
    Membre actif
    Homme Profil pro
    Freelance
    Inscrit en
    Décembre 2003
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : Décembre 2003
    Messages : 423
    Points : 259
    Points
    259
    Par défaut
    Citation Envoyé par sjrd Voir le message
    C'est effectivement le moins qu'on puisse faire. Mais ce n'est pas suffisant. Renommer la méthode serait mieux, car sinon :
    n'est pas équivalent à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var
      Thread: TThread;
     
    Thread := MonThread;
    Thread.Terminate;
    Ce qui est très dangereux, et pas du tout bon question méthode orientée objet.

    Je suis désolé mais là je ne comprends pas ce que tu veux dire ... Un peu de lumière s'il te plaît ?



    Par contre alors, question :
    OK pour donner un autre nom à cette méthode ... Mais comment faire pour ne pas "casser" une certaine logique ... Je vais dire il est assez naturel de cloturer un thread par la méthode prédéfinie de TThread et donc d'invoquer monThread.Terminate ...


    Ne peut-on pas trouver une solution équivalente qui conserverait ce Terminate ?
    Avant d'en dire plus, j'attends ta réponse, ou plutot ton éclaircissement sur ce que j'ai mis au début de ce post ... peut-être alors que les solutions auxquelles je pense ne fonctionneront pas du coup ....

  8. #8
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Citation Envoyé par Bleys Voir le message
    Je suis désolé mais là je ne comprends pas ce que tu veux dire ... Un peu de lumière s'il te plaît ?
    Eh bien je veux dire que selon la façon dont est déclarée la variable, appeler Terminate dessus fera une chose différente ! C'est très dangereux pour la lecture et l'écriture.
    Citation Envoyé par Bleys Voir le message
    OK pour donner un autre nom à cette méthode ... Mais comment faire pour ne pas "casser" une certaine logique ... Je vais dire il est assez naturel de cloturer un thread par la méthode prédéfinie de TThread et donc d'invoquer monThread.Terminate ...
    Comme je l'ai dit plus haut, je conseillerais un nom comme Stop. Oui, tu vas devoir "casser la logique", mais c'est mieux ça que reprendre le même nom, avec tous les problèmes que ça apporte.
    Citation Envoyé par Bleys Voir le message
    Ne peut-on pas trouver une solution équivalente qui conserverait ce Terminate ?
    Non, désolé. C'est un problème du Delphi. Normalement toutes les méthodes devraient être virtuelles dans un langage parfait.

  9. #9
    Membre actif
    Homme Profil pro
    Freelance
    Inscrit en
    Décembre 2003
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : Décembre 2003
    Messages : 423
    Points : 259
    Points
    259
    Par défaut
    Re,

    Oui effectivement ... J'avais pas fait attention à ta déclaration de thread ... Au tant pour moi

Discussions similaires

  1. [JPanel][LayoutManager] redéfinition de méthodes
    Par _KB_ dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 06/06/2006, 15h22
  2. Réponses: 1
    Dernier message: 10/05/2006, 23h07
  3. [Intraweb] Recherche d'exemples de site ?
    Par Damien R dans le forum Web & réseau
    Réponses: 2
    Dernier message: 18/11/2005, 12h27
  4. [JPanel] quel méthode appelé lors du rafraichissement...
    Par lilou77 dans le forum Interfaces Graphiques en Java
    Réponses: 5
    Dernier message: 01/11/2005, 16h08

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