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

C++ Discussion :

[Conception] Problème de visite typée


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 330
    Par défaut [Conception] Problème de visite typée
    Salut,

    J'ai une famille de classes pour lequelles j'ai défini une interface commune pour recevoir un visiteur :

    La classe mère a la méthode suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual void accept(Visitor* visitor);
    qui fait tout simplement :
    La méthode visit du visiteur peut recevoir plusieurs types dans la chaine d'héritage de la classe mère c'est à dire qu'il y a :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Visitor
    {
    public:
    void visit(ClasseMere* instance);
    void visit(ClasseFille1* instance);
    void visit(ClasseFille2* instance);
    }
    Mon problème est le suivant :

    Si je créé un visiteur et que je le donne à la méthode accept() une instance de ClasseFille1 alors le code
    me branche sur la méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void visit(ClasseMere* instance);
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void visit(ClasseFille1* instance);
    Je m'attendrais en effet à ce que visit() s'adapte au type concret ClasseFille1 de mon instance.

    Par contre j'ai remarqué que si je redéfini accept() dans ClasseFille1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual void accept(Visitor* visitor);
    avec un code identique :
    Alors c'est bien la méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void visit(ClasseFille1* instance);
    qui est appelée

    Qui aurait une explication ? Quelle est la bonne façon de faire ?

    Merci

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    La description du pattern Visitor sur Wikipédia indique qu'il faut bel et bien redéfinir la méthode accept()...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 330
    Par défaut
    Citation Envoyé par Médinoc
    La description du pattern Visitor sur Wikipédia indique qu'il faut bel et bien redéfinir la méthode accept()...
    L'exemple de wikipedia ne correspond pas tout à fait à mon cas car "Engine", "Body", "Wheel" n'héritent pas d'une classe "Parts" par exemple.

    L'équivalent de mon problème serait qu'il y ait une classe "Parts" mère de "Engine", "Body", "Wheel" et qui définirait accept() comme faisant :

    Je ne vois pas alors pourquoi ce code hérité de "Parts" ne marcherait pas en adaptant l'appel de "visit()" au type concret de "this" lorsqu'il est appelé depuis les classes filles "Engine", "Body", "Wheel".

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Parce que le choix de l'une ou l'autre méthode visit() dépend du type statique de l'argument qu'on lui passe.

    C'est le principe même du pattern Visitor.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre éclairé
    Inscrit en
    Mai 2006
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 330
    Par défaut
    Citation Envoyé par Médinoc
    Parce que le choix de l'une ou l'autre méthode visit() dépend du type statique de l'argument qu'on lui passe.

    C'est le principe même du pattern Visitor.
    Ah d'accord, je n'avais pas compris cette subtilité... celà explique en effet le comportement observé.

    Dois-je en conclure que je n'ai pas d'autre alternative que de définir un accept spécifique pour chacune de mes classes ?

    N'y aurait-il pas un moyen de s'en sortir avec une utilisation des templates par exemple ?

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Avec les templates, peut-être en CRTP (curiously recurring template pattern) avec une classe intermédiaire TParts qui serait le template.
    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
    class Parts
    {
       virtual void accept(Visitor * pVisitor) = 0;
    }
     
    template< class T >
    class TParts : public Parts
    {
        virtual void accept(Visitor * pVisitor)
        {
            pVisitor->visit(static_cast< T* >(this);
        }
    };
     
    class Engine : public TParts< Engine >
    {
    };
     
    //etc.
    Note que la classe TParts réimplémente quand même la méthode accept(). Par contre, les classes qui en dérivent n'en ont pas besoin, puisque le type statique est le bon.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

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

Discussions similaires

  1. [Conception] problème avec firefox sur les champs input type="file"
    Par maverick56 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 9
    Dernier message: 11/05/2007, 10h57
  2. [Conception] Problème avec input type="text"
    Par adrix26 dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 02/03/2007, 10h52
  3. [Débutant][Phppgadmin] problème avec les types
    Par PoY dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 19/08/2004, 17h06
  4. [jointure] Petit problème sur le type de jointure...
    Par SteelBox dans le forum Langage SQL
    Réponses: 13
    Dernier message: 13/02/2004, 18h55
  5. Problème avec le type 'Corba::Any_out'
    Par Steven dans le forum CORBA
    Réponses: 2
    Dernier message: 14/07/2002, 18h48

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