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 :

Copie de liste hétérogène


Sujet :

Langage Delphi

  1. #1
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    190
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 190
    Points : 83
    Points
    83
    Par défaut Copie de liste hétérogène
    Bonjour,

    J'aimerai savoir comment utiliser la methode "assign" pour copier une liste hétérogène...

    Je m'explique.
    J'ai une class mère (TFiltre) avec plusieurs classes filles et petites-filles (et ainsi de suite) (TFiltreNumerique, TFiltreTextuel, TFiltreTextuelBidule, ...)

    J'ai une TStringList qui héberge indifféremment des instances de ces classes dérivées ou éventuellement des instances de la classe mère.

    Je ne parviens pas à utiliser assign (je dois mal comprendre son fonctionnement) pour creer une seconde liste qui ai les même valeurs que la première, mais avec pourtant des objets différents (cad si je change la proprieté d'un des objets recrée en copiant, que ça ne change pas la même proprieté de l'objet symétrique ayant été copié)

    Avant :
    • L1-o1-o2-o3-o4
      L2-


    Ce que je veux :
    • L1-o1-o2-o3-o4
      L2-o1'-o2'-o3'-o4'


    Ce que je ne veux pas :
    • L1-o1-o2-o3-o4
      L2-o1-o2-o3-o4


    Quelqu'un peut-il m'expliquer ça ?

    Merci d'avance !
    Pour mes développements, j'utilise :
    WinX-64bits, Delphi Tokyo 10.2.2
    Merci, merci, merci... moi aussi je vous aime, c'est trop d'émotions...
    Key user des blagues nulles

  2. #2
    Membre averti
    Profil pro
    xxxxxxxxxxx
    Inscrit en
    Juin 2004
    Messages
    308
    Détails du profil
    Informations personnelles :
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : xxxxxxxxxxx

    Informations forums :
    Inscription : Juin 2004
    Messages : 308
    Points : 407
    Points
    407
    Par défaut
    assign ne permettra pas cela ; écrire une méthode "cloner" qui recrée des instances et copie le contenu.

  3. #3
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    190
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 190
    Points : 83
    Points
    83
    Par défaut
    Cela signifie-t-il que ma méthode "cloner" devra connaitre toutes les classes filles et faire quelque chose du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    for iCpt := 0 to Source.count -1 do begin
        if Source.object[iCpt].ClassName='FiltreNumerique' then begin
            Creer un objet de class "FiltreNumerique"
            Copier dedans les proprietés de sources
            L'insérer dans ma liste clone
            end;
        if Source.Object[iCpt].ClassName = 'Une Autre classe fille' then begin
            Recommencer avec un autre cast !!!
            end;
        Recommencer avec toutes les classes descendantes !!!
        end;
    Pour mes développements, j'utilise :
    WinX-64bits, Delphi Tokyo 10.2.2
    Merci, merci, merci... moi aussi je vous aime, c'est trop d'émotions...
    Key user des blagues nulles

  4. #4
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    190
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 190
    Points : 83
    Points
    83
    Par défaut
    Existe-t-il une façon de faire un peu plus concise ?

    Voici comment de fait actuellement... je suis sur que l'on peut mieux faire...

    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
     
    procedure TListeDeFiltre.Assign(Source: TPersistent);
        var
            iCpt : integer ;
            Filtre : TFiltre ;
            sNomClass : String ;
        begin
            inherited;
            for iCpt := 0 to slListeDeFiltre.Count -1 do begin
                slListeDeFiltre.Objects[iCPt].Free;
                end;
            slListeDeFiltre.Clear ;
            for iCpt := 0 to TListeDeFiltre(Source).slListeDeFiltre.Count -1 do begin
                sNomClass := TListeDeFiltre(Source).slListeDeFiltre.Objects[iCpt].ClassName ;
                if (sNomClass = 'TListeDeFiltre' ) then begin
                    Filtre := TListeDeFiltre.Create();
                    TListeDeFiltre(Filtre).Assign(TPersistent(TListeDeFiltre(Source).slListeDeFiltre.Objects[iCpt]));
                    end;
                if (sNomClass = 'TListeDeFiltreEt' ) then begin
                    Filtre := TListeDeFiltreEt.Create();
                    TListeDeFiltreEt(Filtre).Assign(TPersistent(TListeDeFiltre(Source).slListeDeFiltre.Objects[iCpt]));
                    end;
                if (sNomClass = 'TListeDeFiltreOu' ) then begin
                    Filtre := TListeDeFiltreOu.Create();
                    TListeDeFiltreOu(Filtre).Assign(TPersistent(TListeDeFiltre(Source).slListeDeFiltre.Objects[iCpt]));
                    end;
                if (sNomClass = 'TFiltre' ) then begin
                    Filtre := TFiltre.Create();
                    TFiltre(Filtre).Assign(TPersistent(TListeDeFiltre(Source).slListeDeFiltre.Objects[iCpt]));
                    end;
                if (sNomClass = 'TFiltreTextuel' ) then begin
                    Filtre := TFiltreTextuel.Create();
                    TFiltreTextuel(Filtre).Assign(TPersistent(TListeDeFiltre(Source).slListeDeFiltre.Objects[iCpt]));
                    end;
                { LE PROBLEME, C'EST QUE J'EN AI ENCORE BCP D'AUTRES CLASSES DERIVEES !!!  }
                { BIEN SUR, JE NE LES METS PAS TOUTES ICI }
                { AUTRE INCONVENIENT, JE DOIS FAIRE UN "USE" DE TOUTES MES UNITEES...  }
                slListeDeFiltre.AddObject(Filtre.sExplication,TObject(Filtre));
                end;
            end;
    Pour mes développements, j'utilise :
    WinX-64bits, Delphi Tokyo 10.2.2
    Merci, merci, merci... moi aussi je vous aime, c'est trop d'émotions...
    Key user des blagues nulles

  5. #5
    Membre habitué Avatar de gord's
    Inscrit en
    Avril 2003
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 115
    Points : 127
    Points
    127
    Par défaut
    vague idée : tu pourrais dans tes classe déclarer une fonction "clone", qui crée un objet identique à celui qui reçoit cette méthode, et le retourne.
    déclares là en virtual abstract dans ta classe ancetre, chqrge aux descendantes de l'implémenter.

    dans ta copie de liste, tu n'as qu'a caster l'objet à dupliquer dans la classe ancetre, et tu n'as pas besoin de tenir compte de la classe effective, ni d'inclure les units correspondantes.

    Voila, c'est réfléchi un peu vite, il faut surement approfondir.
    La prochaine révolution informatique : les machines qui font ce qu'on veut, au lieu de faire ce qu'on leur demande...
    Grand Vizir du Grand Gourou - Trois-quart aile gauche du TRFC et intendant de 3ème mi-temps - Papy fait de la résistance

  6. #6
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    190
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 190
    Points : 83
    Points
    83
    Par défaut
    Mais c'est bien sur !

    Quelle bonne idée...

    En créeant une fonction dans toutes mes classes dérivées et/ou dans la classe ancètre comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function TUneClassFille.Cloner(): TClassAncetre;
        begin
            result := TUneClassFille.Create();
            TUneClassFille(result).Assign(self);
            end;
    Ensuite, pour dupliquer ma liste hétérogène, je n'ai plus qu'à implémenter la fonction suivante :

    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
    procedure TListeDeFiltre.Assign(Source: TPersistent);
        var
            iCpt : integer ;
            Filtre : TFiltre ;
        begin
            inherited;
            for iCpt := 0 to slListeDeFiltre.Count -1 do begin
                slListeDeFiltre.Objects[iCPt].Free;
                end;
            slListeDeFiltre.Clear ;
            for iCpt := 0 to TListeDeFiltre(Source).slListeDeFiltre.Count -1 do begin
                Filtre := TFiltre(TListeDeFiltre(Source).slListeDeFiltre.objects[iCpt]).Cloner();
                slListeDeFiltre.AddObject(TFiltre(Filtre).sExplication,Filtre);
                end;
            end;
    Et le tour est joué !

    Merci gord's !
    Pour mes développements, j'utilise :
    WinX-64bits, Delphi Tokyo 10.2.2
    Merci, merci, merci... moi aussi je vous aime, c'est trop d'émotions...
    Key user des blagues nulles

  7. #7
    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 152
    Points
    10 152
    Par défaut
    Oui, c'est une façon propre et bien faite . Mais, si tu aimes les astuces les plus profondes du Pascal Objet, essaie ça.
    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
    procedure TListeDeFiltre.Assign(Source : TPersistent);
    var I : integer;
        slSource : TStrings;
        Filtre : TFiltre;
        TFiltreClass : class of TFiltre;
    begin
      inherited;
      for I := 0 to Count-1 do slListeDeFiltre.Objects[I].Free;
      slListeDeFiltre.Clear;
      slSource := TListeDeFiltre(Source).slListeDeFiltre;
      for I := 0 to slSource.Count-1 do
      begin
        Filtre := TFiltreClass(slSource.Objects[I].ClassType).Create;
          // Crée un descendant de TFiltre de même classe que la source
        Filtre.Assign(TFiltre(slSource.Objects[I]));
          // Assign depuis la source
        AddObject(slSource[I], Filtre);
          // Ajout à la liste
      end;
    end;
    Pour que ce code fonctionne, tu dois déclarer le constructeur (Create) de ta classe TFiltre en virtual et celui de tous ces descendants en override. Comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    TFiltre = class(TPersistent)
      ...
    public
      constructor Create; virtual;
      ...
    end;
     
    TDescendantDeTFiltre = class(TFiltre)
      ...
    public
      constructor Create; override;
      ...
    end;
    Si tu comprends pas le principe, demande
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

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

Discussions similaires

  1. Copie de liste de fichier
    Par jemini_fr dans le forum ANT
    Réponses: 6
    Dernier message: 22/10/2008, 17h45
  2. [VBA-EXCEL]Copie de listes nommées
    Par lucarno dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 09/07/2007, 23h51
  3. constructeur de copie (class Liste)
    Par crischprolch dans le forum C++
    Réponses: 7
    Dernier message: 11/05/2006, 15h59
  4. copie de liste chainée
    Par tomsoyer dans le forum C++
    Réponses: 15
    Dernier message: 31/08/2004, 18h20
  5. Copie de Liste
    Par Arnaud-h dans le forum C++Builder
    Réponses: 2
    Dernier message: 06/05/2004, 14h46

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