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 C++ Discussion :

list et methodes virtuelles


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 162
    Par défaut list et methodes virtuelles
    Salut,

    le probleme que je soulève est surement bateau mais je ne le comprends pas.
    J'ai la hiérarchie de classe 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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    class Widget {
    public:
        Widget() {}
     
        virtual ~Widget() {}
     
        virtual void draw() = 0;
    };
     
    class Button : public Widget {
    public:
     
        //! Constructs a new button.
        Button() : Widget() {
     
        }
     
        ~Button() { }
     
        //! Draw the widget on screen
        void draw();
     
        virtual void handleFocusLost();
     
     
    };
     
    class ToggleButton : public Button{
    public:
        //! Constructs a new button.
        ToggleAction(int x);
     
        virtual void handleFocusLost();
    };
    Ce sont des widgets pour une interface graphique. Il y a des boutons et des boutons particuliers, les ToggleButton.

    Par ailleurs j'ai une classe Menu qui affiche tous ses widgets et qui maintient donc une liste de widget, déclarée ainsi dans la classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::list<Button> actions_;
    Finalement, dans une méthode de la classe Menu, je parcours les widgets pour en appeler la méthode handleFocusLost() ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    for (std::list < Button>::iterator it = actions_.begin();
             it != actions_.end(); it++) {
            Button & b = *it;
     
            b.handleFocusLost();
        }
    Mais a l'exécution (en mettant une trace spécifique a chaque implémentation de méthode), le code précédent appelle systématiquement l'implémentation de la classe Button même si j'ai à faire à une instance de ToggleButton.
    Pourquoi est-ce le cas? La méthode handleFocusLost() est pourtant déclarée virtuelle.
    J'ai remarqué que j'ai un bon fonctionnement lorsque j'utilise des pointeurs tel que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::list<Button*> actions_;
    Quelqu'un a t-il l'explication?

  2. #2
    Membre confirmé

    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 133
    Par défaut
    Ca donne quoi si tu remplaces

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            Button & b = *it;
            b.handleFocusLost();
    Par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            (*it).handleFocusLost();
    ?

    J'imagine que quand tu mets dans b tu perds les informations relatives à la classe fille.


    En tout cas je ne sais pas quelle est la bonne pratique, mais moi j'utilise systématiquement des pointeurs plutôt que des objets directement.
    Si t'as un pointeur tu peux le caster comme t'as envie, alors que si tu caste un objet je pense que tu peux perdre de l'information ...

    Que quelqu'un me corrige si je me trompe, je n'ai pas l'habitude de donner des conseiuls ici


    EDIT : j'essaie d'expliquer où je veux en venir : quand tu fais <Button> il stocke effectivement un Button et rien de plus. Tout ce qui dépasse est perdu. Et si tu fais <Button*> tu stockes quoiqu'il arrive une adresse, et ce qui se trouve à cette adresse peut être de type Button ou un descendant.

  3. #3
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 295
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 295
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    je suis d'accord avec Michel_57: en faisant le cast (Button & b = *it; est un cast; caché, mais c'est bien un cast), tu perd la "partie" fille de l'élément.

  4. #4
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Salut,

    C'est un problème de slicing.

    MAT.

  5. #5
    Membre éprouvé Avatar de nowahn
    Homme Profil pro
    Inscrit en
    Août 2008
    Messages
    84
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 84
    Par défaut
    Salut,

    Pour préciser, c’est bien un problème de slicing, au moment du stockage du bouton dans la liste (tu ne peux rien y changer en modifiant le code du corps de ta boucle for, le slicing a eu lieu avant).

    La solution est d’utiliser :
    et même certainement mieux avec des pointeurs intelligents à la place des pointeurs simples.

  6. #6
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 295
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 295
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par nowahn Voir le message
    La solution est d’utiliser :
    Il existe bien d'autres solutions

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 13/02/2007, 15h29
  2. Réponses: 2
    Dernier message: 20/10/2006, 15h07
  3. [debutant] probleme avec methode virtuelle pure
    Par Treuze dans le forum Débuter
    Réponses: 10
    Dernier message: 21/04/2006, 12h58
  4. Réponses: 19
    Dernier message: 10/02/2005, 22h43
  5. [Language] Méthodes virtuelle ?
    Par Eltaz dans le forum Langage
    Réponses: 2
    Dernier message: 12/01/2005, 21h43

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