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

Delphi Discussion :

[POO]Probléme de constructeur virtuel surchargé


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Billets dans le blog
    1
    Par défaut [POO]Probléme de constructeur virtuel surchargé
    Salut,
    j'ai un petit soucis avec des constructeurs virtuels surchargé.

    Le contexte :
    voici un code d'exemple avec les déclarations des différents constructeurs :
    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
     
    program ConstructeurVirtuelSurcharge;
     
    {$APPTYPE CONSOLE}
     
    uses
      SysUtils;
     
    type
      TMere=Class
      public
        constructor Create(A:String;S:String);Overload;Virtual;
        constructor Create; reintroduce; overload; virtual;
        //constructor Create(A:String;B:Integer);Overload;Virtual;Abstract;
        //constructor Create(A:String;B:Pointer);Overload;Virtual;Abstract;
      end;
     
      TFille = class(TMere)
      public
       constructor Create(A:String;B:Integer);reintroduce;Overload;
      end;
     
      TFils = class(TMere)
      public
       constructor Create(A:String;B:Pointer);reintroduce;Overload;
      end;
     
      TPetiteFille = class(TFille)
      public
       constructor Create(A:String;B:Double);reintroduce;Overload;
      end;
     
     TMereClass = Class of TMere;
     TFilleClass = Class of TFille;
     TPetiteFilleClass = Class of TPetiteFille;
     
    { TMere }
     
    constructor TMere.Create;
    begin
     
    end;
     
    constructor TMere.Create(A:String;S:String);
    begin
     
    end;
     
    { TFille }
    constructor TFille.Create(A:String;B:Integer);
    begin
    end;
     
    { TFils }
     
    constructor TFils.Create(A: String; B: Pointer);
    begin
     
    end;
     
    { TPetitEnfant }
     
    constructor TPetiteFille.Create(A: String; B: Double);
    begin
     
    end;
     
    var clsOfTMere :TMereClass;
        clsOfTFille :TFilleClass;
        R:TMere;
     
    begin
      R:=TFille.create('S',Integer(1)); //Create de TFille
      R.free;
      R:=TFille.create('S','S1');//Create de TMere
      R.free;
     
    { code à simplifier
      if type='fils'
       then  R:=TFils.Create('S',1) //Create de TFils
       then  R:=TFille.Create('S',1) //Create de TFille
     }
      clsOfTMere:=TFille;
      R:=ClsOfTMere.Create('S','S2'); //Create de TMere
      R.Free;
       //Erreur à la compilation :
       //There is no overloaded version of 'create' that can be called with these arguments (E2250)
      R:=ClsOfTMere.Create('S',1); // Create de TFille
      //Un cast TFille(ClsOfTMere) fonctionne mais ne simplifie pas le code
      R.Free;
     
      clsOfTMere:=TFils;
      R:=ClsOfTMere.Create('S','S2'); //Create de TMere
      R.Free;
       //Erreur identique à la compilation 
      R:=ClsOfTMere.Create('S',Nil); //Create de TFils
      //R.Free;
     
      clsOfTFille :=TFille;
      R:=ClsOfTFille.Create('S','S2');//Create de TMere
      R.Free;
      R:=ClsOfTFille.Create('S',1);//Create de TFille
      R.Free;
    end.
    L'objectif :
    J'aimerais modifié un code existant ressemblant à qq chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      if type='fils'
       then  R:=TFils.Create('S',1) //Create de TFils
       then  R:=TFille.Create('S',1) //Create de TFille
    en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
      type  TMereClass = Class of TMere;
      ...
      if type='fils'
       then  clsOfTMere:=TFils
       then  clsOfTMere:=TFille,
     
      ClsOfTMere.Create('S',1) //Create de TFils ou de TFille
    Je pensais que l'utilisation d'une référence de classe pouvait m'aider à simplifier ce code mais sur un appel de constructeur surchargé déclaré dans une classe dérivée, j'ai l'erreur suivante à la compilation :
    There is no overloaded version of 'create' that can be called with these arguments (E2250)
    Un cast TFille(ClsOfTMere).create(...) fonctionne mais ne simplifie pas le code.

    Comment résoudre ce cas, ie. utiliser de maniére générique un constructeur virtuel surchargé déclaré dans des classes dérivées ?

    L'ajout dans la classe ancêtre (TMere) des prototypes suivants:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
       constructor Create(A:String;B:Integer);Overload;Virtual;Abstract;
       constructor Create(A:String;B:Pointer);Overload;Virtual;Abstract;
    régle le probléme mais dans mon contexte je ne peux pas modifier la classe ancêtre existante.
    J'utilise Delphi 2006 qui permet l'usage de ClassHelper mais je préfére éviter cette solution.
    J'ai bien peur que cela soit insoluble, à moins que...

    En espérant avoir été assez clair.

  2. #2
    Membre Expert

    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 897
    Par défaut
    Laurent,

    Est-ce que ton exemple précédent reflète-t-il le code que tu dois traiter où est-ce un exemple que tu as construit pour décrire ton problème ?
    Je m'explique, les classes que tu utilises instancient-elles des objets persistant ?

    Si c'est le cas, alors en utilisant RegisterClass, tu enregistres tes classes et avec FindClass tu les retrouveras à partir de leur nom. Ce qui simplifie énormément l'instanciation de nouveau objets uniquement à partir de leur nom de classe.

    Je ne sais pas si cela peut répondre à ton problème, en espérant te donner peut-être une piste

  3. #3
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Billets dans le blog
    1
    Par défaut
    Salut Pascal,
    Citation Envoyé par Pascal Jankowski
    Est-ce que ton exemple précédent reflète-t-il le code que tu dois traiter où est-ce un exemple que tu as construit pour décrire ton problème ?
    A l'origine il s'agit d'une hiérarchie de classe dérivée de TForm.
    Citation Envoyé par Pascal Jankowski
    Si c'est le cas, alors en utilisant RegisterClass, tu enregistres tes classes et avec FindClass tu les retrouveras à partir de leur nom. Ce qui simplifie énormément l'instanciation de nouveau objets uniquement à partir de leur nom de classe.
    Je m'aperçois qu'en simplifiant le code pour tester ce cas je me suis égaré .
    Ton approche résoud le probléme mais je reste curieux quant à la solution pour des classes ne posssédant pas la méthode RegisterClass.

    Un collégue m'a proposé d'avoir un seul constructeur possédant un nombre variable de paramètres T.Create(Param : array of const);, c'est une solution mais c'est une modélisation un peu brut de décoffrage

    Merci

  4. #4
    Membre Expert

    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 897
    Par défaut
    Citation Envoyé par Laurent
    A l'origine il s'agit d'une hiérarchie de classe dérivée de TForm.

    bon je pense que cela résout ton problème et j'en suis heureux
    Après avoir enregitré ta classe un simple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    TFormClass(findClass(classNom)).Create(..... );
    Va simplifier ton code pour l'intanciation

    Pas besoin de caster, et tu retrouves un aspect générique...

    Cela ne fonctionne pas hélas pour les objets non persistant. Pas d'enregistrement dans le flux VCL ce qui est bien dommage !

  5. #5
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Billets dans le blog
    1
    Par défaut
    Aprés modification du code :
    DetailWindow := TfrmAncestorDetailClass(FindClass(NomDeClasse)).Create (Self, sViewModeDesc, FieldByName ('rqst_id').AsInteger, FieldByName ('rqst_no').AsInteger);
    end;
    Le problème persiste, même msg d'erreur à la compilation, car je dois caster la classe trouvée avec un référence de classe qui ne contient pas le prototype du constructeur utilisé.
    Je pense que je vais laisser comme ça, le mieux étant l'ennemi du bien

  6. #6
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2002
    Messages
    520
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 520
    Par défaut
    J'ai deux trois idées mais faut que j'essaie avant :-)
    Mais j'ai du mal à voir si le problème principal est de trouver le type de la classe à instancier, ou d'instancier une classe de type connu avec un constructeur correctement signé ?

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

Discussions similaires

  1. [POO] Problème avec un constructeur
    Par jpean.net dans le forum Débuter
    Réponses: 34
    Dernier message: 19/11/2009, 23h14
  2. Réponses: 3
    Dernier message: 28/11/2008, 14h02
  3. Réponses: 13
    Dernier message: 31/10/2008, 13h32
  4. [POO] problème de surcharge des parenthèses
    Par oswalidos dans le forum C++
    Réponses: 10
    Dernier message: 27/10/2008, 09h23
  5. [POO] Problème de surcharge
    Par Mr.MoOx dans le forum Langage
    Réponses: 1
    Dernier message: 14/04/2007, 19h54

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