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 :

Masquer la procedure TObject.Free ?


Sujet :

Langage Delphi

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    292
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 292
    Points : 222
    Points
    222
    Par défaut Masquer la procedure TObject.Free ?
    J'ai un objet(Objet1) qui contient une référence vers un autre objet(Objet2 pour faire simple) et qui est responsable de sa création/destruction. Cependant, il peut fournir la référence "à l'extérieur".

    autant je peux rendre private les constructor et destructor de la classe de Objet2 et ainsi fournir une interface public clean, autant si Objet2 est typecast en TObject et Free est utilisée je l'ai dans l'os.

    avant de rajouter un moyen dans la classe de vérifier si l'appel à destroy est valide où pas ( par exemple mettre une variable private qui ne pourrait être accédée que par l'objet responsable du cycle de vie, par exemple une référence à Objet1 qui serait mise à nil au moment de l'appel à Free par Objet1 justement et de tester dans destroy si Reference == nil), je me demandais si y avait un moyen autre qui m'aurait échappé.

    et la méthode entre paranthèse a l'inconvénient d'être une méthode dynamique. alors qu'elle serait là pour prévenir une erreur statique, c a d un appel d'une méthode que le programmeur n'aurait pas du faire.

  2. #2
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 740
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 740
    Points : 13 283
    Points
    13 283
    Par défaut
    autant je peux rendre private les constructor et destructor de la classe de Objet2
    Non, ce n'est pas possible. Tu ne peux pas diminuer la visibilité d'une méthode.

    Le seul moyen est de ne pas donner directement accès à Object2 et d'encapsuler les appels à certaines procédures intéressantes dans des méthodes de Object1.

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

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 862
    Points : 11 318
    Points
    11 318
    Billets dans le blog
    6
    Par défaut
    au lieu de fournir une référence à l'objet, ne devrait-il pas fournir simplement une interface, qui n'implémenterait pas de destructeur ?
    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 !

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    292
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 292
    Points : 222
    Points
    222
    Par défaut
    oui. je disais simplement je pouvais empêcher Object2.destroy et Object2.Free et TClass2.Create mais pas TObject(Objet2).Free et je suis d'accord pas TObject(Objet2).destroy

    pour ce qui est de l'interface, oui à condition d'implémenter les fonctions QueryInterface et le tralala ou dériver d'une classe qui les implémente (ce qui n'est pas toujorus possible vu qu'on peut pas faire de dérivations multiples). donc c pas mal

    mais je me demandais si y avait d'autres truc plus léger. en fait je me demandais si j'avais raté un truc dans le langage. ou qqch dans le genre.

  5. #5
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par Bruno75 Voir le message
    oui. je disais simplement je pouvais empêcher Object2.destroy et Object2.Free et TClass2.Create mais pas TObject(Objet2).Free et je suis d'accord pas TObject(Objet2).destroy

    pour ce qui est de l'interface, oui à condition d'implémenter les fonctions QueryInterface et le tralala ou dériver d'une classe qui les implémente (ce qui n'est pas toujorus possible vu qu'on peut pas faire de dérivations multiples). donc c pas mal

    mais je me demandais si y avait d'autres truc plus léger. en fait je me demandais si j'avais raté un truc dans le langage. ou qqch dans le genre.
    C'est possible, à condition de faire appel à Mr Indestrutible

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    type
      TIndestructible = class(TObject)
      protected
        procedure BeforeDestruction; override;
      end;
     
    procedure TIndestructible.BeforeDestruction;
    begin
      Abort;
    end;
    Attention cependant, Abort est une exception silencieuse, donc un appel au destructeur ne détruit pas l'objet mais interrompt le code

    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
     
    procedure TForm1.FormCreate(Sender: TObject);
    var
      MrIndestructible : TIndestructible;
      Index : Integer;
    begin
      FList := TList.Create;
      for Index := 0 to 100 do
      begin
        MrIndestructible := TIndestructible.Create;
        FList.Add(MrIndestructible);
        try
          MrIndestructible.Free;
        except
          // cause of Abort exception
        end;
      end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 516
    Points : 25 033
    Points
    25 033
    Par défaut
    Pourquoi ne pas gérer lors de l'accesseur, un flag qui indique que l'objet est affecté de l'extérieur ... lorsque Objet2 est interne, il est manipulé via le membre Privé (FObjet2) et en externe par la propriété Objet2 ...

    Quel est l'ancêtre de TObjet2 ? le TComponent avec son Owner te premettrait d'oublier ces petits tracas ...

    Ou fait une sorte de Register où tu indique à la Classe TObjet1 une liste d'objet à ne pas libérer ... (sorte de GarbageCollector à l'envers)

    Ou encore tu mets une propriété Owned dans Objet2 qui indiquera si il est libéré par Objet1...

    Ou encore tu ne pratique que par Clonage d'objet, ainsi les références sont idenpendantes (tu peux mettre en place un mecanisme qui maintient les données des instances clonées au même valeur ... jusqu'au moment où tu détache complètement un clone ...)

    Ce Mr Indestrutible, c'est juste une grosse fuite mémoire ... mieux vaut passer par un mécanisme Notification avant la Libération ?

    Tu pourrais repartir de la problématique d'origine, tu bloques l'analyse de ton problème à la libération interdite depuis l'extérieure ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Membre éclairé Avatar de Kaféine
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 569
    Points : 736
    Points
    736
    Par défaut
    Salut,

    Mr indestructible

    il est jamais libéré. (bah oui il est indestructible !)

    peut lui ajouter un état IsIndestructible commutable pour qu'il crève un jour au moins
    Akim Merabet

  8. #8
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par Kaféine Voir le message
    Salut,

    Mr indestructible

    il est jamais libéré. (bah oui il est indestructible !)

    peut lui ajouter un état IsIndestructible commutable pour qu'il crève un jour au moins
    ah mais dans ce cas ce n'est pas le même composant ^^

    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
     
    type
      TAchile = class
      private
        FTalon : Boolean;
      protected
        procedure BeforeDestruction; override;
      public
        property Talon: Boolean read FTalon write FTalon;
      end;
     
    procedure TAchile.BeforeDestruction;
    begin
      if not FTalon then Abort;
      inherited;
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    292
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 292
    Points : 222
    Points
    222
    Par défaut
    Ok je vois un peu mieux ou ca coince. en fait, ce qui me gêne c plus un problème de 1 comment faire comprendre (doc, code, etc.) comment est géré la vie d'un composant à qqn qui voudrait juste l'utiliser. 2 quand laisser ou ne pas laisser des manières de faire planter le code.

    1
    qd on récupère une interface, on sait qu'il suffit de la mettre à nil et c bon
    qd je fais un create, soit je devrait faire un Free plus tard, soit je refile le bébé à qqn d'autre, par exemple une TObjectList.Create(True)
    2
    ex en Delphi, si je Free 2 fois le même objet ou si j'écrit nimporte comment dans des tableaux

    donc dans mon cas la question serait est ce que
    - je devrais mettre en place une interface ?
    - gérer un appel intempestif à Free ?
    - simplement mettre une ligne dans la doc ?
    - plus ou moins faire apparaître un pattern connu ?

    je précise peut être mon exemple (je rappelle que le but est plus d'expliciter ce dont je parlais, et pas de partir sur une discussion sur la conception de gestion d'événements)
    - 1 table en base TBL_DATA
    - 1 classe qui interface le code et la base et lance des événements. TDAL
    - 1 collecteur d'événement (Objet1) qui permet stocker les événements pour les gérer après coup. asynchrone. TEventServer
    - 1 vue qui est intéressée par les événements de données de la classe d'interface. TView

    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
     
    EventServer =  TEventServer.Create
    Dal := TDal.Create
    View := TView.Create
     
    //TDal a 2 events OnNewRow et OnDelRow qui trigger 
    // si l'insertion ou la deletion a eu lieu avec succès.
     
    TDal.TCreate
        OnNewRow = EventServer.NewEvent
        //OnNewRow est l'objet2 dont je parlais
    end
     
    TView.TCreate
       Dal.OnNewRow.Register(View.UneMethodDeGestion)
    end
     
    // plus tard au moment d'une insertion
     
    TDal.NewRow
       //Code d'insertion
       OnNewRow.Trigger(RowId)
    end
     
    TDal.Destroy
       OnNewRow.Free // ??????
    end
    bon c un mauvais exemple vu que d'une certaine manière on pourrait s'attendre à si ce n'est un Free au moins un Release. je vous laisse commenter, peut être le questionnement que j'ai correspond à un cas qui n'existe pas je sais pas. mais je me dit qu'est ce qui va faire que le programmeur ne va pas faire un OnNewRow.Free, dois-je le gérer ? si je met une fonction release je dois me debrouiller pour que Free = Release ?
    etc .

  10. #10
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    ok, sauf si ton code est plus complexe, personnellement je n'utiliserais pas un objet

    deux approches:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    // première approche, OnNewRecord: TNotifyEvent
    TDal.TCreate
        OnNewRow = View.UneMethodDeGestion;
    end
    // rien à libérer
     
    // seconde approche, associer un objet et une méthode dans le serveur d'events
    EventServer.RegisterMethod(Dal, View.UneMethodeDeGestion);
    // et pour libérer
    EventServer.UnRegisterMethod(Dal, View.UneMethodeDeGestion);
    le truc que je ne comprend pas dans ton exemple, c'est ce que vient faire le EventServer dans tout cela
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  11. #11
    Membre actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    292
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 292
    Points : 222
    Points
    222
    Par défaut
    je pense vaut mieux clore le sujet, je crois j'ai pas été suffisament clair dans mon propre questionnement. je vais prendre le temps de reréfléchir à tout ça et si besoin je referai une nouvelle discussion.

    @PaulToth : je me suis interessé à 1 vue mais en fait y en a plusieurs qui s'interessent à l'événement OnNewRow. d'ou le fait que OnNewRow soit un objet et non une méthode.
    et ensuite, je fait une file d'attente d'événements, je ne souhaite pas callback directement dans le code de la vue. d'où le server. qui permet une notification asynchrone.

  12. #12
    Membre éclairé Avatar de Kaféine
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 569
    Points : 736
    Points
    736
    Par défaut
    TAchille et son talon

    Haha humour quand tu nous tient!
    Akim Merabet

Discussions similaires

  1. Procedure Free vs. Destructor Destroy
    Par MiJack dans le forum Langage
    Réponses: 5
    Dernier message: 02/10/2013, 13h21
  2. Probleme chez Free lors de la procedure de demanagement
    Par candice9 dans le forum Dépannage et Assistance
    Réponses: 2
    Dernier message: 18/08/2008, 16h32
  3. Masquer le curseur en mode MS-DOS
    Par Alex120 dans le forum C
    Réponses: 2
    Dernier message: 10/07/2002, 09h30
  4. Comment masquer le curseur de la souris ?
    Par benj63 dans le forum C++Builder
    Réponses: 4
    Dernier message: 26/06/2002, 18h54
  5. TObject->Color et composantes RGB
    Par Flo. dans le forum C++Builder
    Réponses: 10
    Dernier message: 14/06/2002, 17h07

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