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 :

heritage, substitution et std::list


Sujet :

C++

  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2013
    Messages : 6
    Par défaut heritage, substitution et std::list
    Bonjour,

    Je suis face à un problème dans un projet de cpp assez conséquent (à ma petite échelle tout du moins) avec de l'opengl . Je vais essayer de vous synthétiser mon problème :

    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
     
     
    /**
     * Classe représentant l'entité de base de la représentation des mobiles. Ces entitées
     * sont lié dans une structure d'abres les unes aux autres pour former un mobile.
     * expl : la brique Tete est lié à la brique corps du personnage qui est lié aux briques
     * bras etc ...
     */
    class Brique {
            protected:
            /**
             * vecteur des briques suivantes dans l'arbre
             */
            std::vector<Brique> suivants;
     
            public:
            /**
             * Constructeur
             */
            Brique(...);
     
            /**
             * Fonction dessinant la brique
             */
            virtual void dessinerBrique();
    };
     
    class Brique_particulaire: public Brique {
        public:
        /**
         * Constructeur
         */
        Brique_particulaire(...);
     
         /**
          * Fonction dessinant la brique particulaire
          */
          void dessinerBrique();
    };
     
    /**
     * Un mobile est un objet affichable constitué d'un arbre de briques
     */
    class Mobile {
    protected:
        	/**
             * Arbre des briques de ce modele.
             */
    	Brique* arbre_briques;
    public:
            blabla...
     
            /**
             * Constructeur
             */
            Mobile() {
     
             }
     
             /**
              * dessine le mobile en parcourant recursivement toutes ses briques et
              * les dessinant une a une les unes par rapport aux autres
              */
             void dessinerMobile();
    };
     
    /**
     * Un projectile est un mobile particulier qui contient uniquement une brique particulaire
     */
    class Projectile: public Mobile {
     public:	
    	Projectile();	
    };
     
    /**
     * \class Mobiles_liste : Classe liste de tout les mobiles utile pour
     * l'affichage entre autre.
     */
    class Mobiles_liste : public std::list<Mobile> {
     public : 
    	/**
             * Fonction affichant tout les mobiles
             */
    	void draw() {
                for (std::list<Mobile>::iterator it = this->begin(), end = this->end(); it != end; ++it) {
    		it->dessinerMobile();
    	    }
            }
    };
    Mon problème est le suivant : lorsque je mets un Projectile dans la Mobile_liste son affichage se fait comme si la brique dans projectile n’était pas particulaire mais simplement une brique. C'est à dire qu'il va faire appelle à Brique::dessinerBrique(); au lieu de faire appelle à Brique_particulaire::dessinerBrique();

    Je ne comprends pas pourquoi et je n'arrive pas à contourner le problème...

    En espérant avoir été suffisamment clair, merci par avance

  2. #2
    Membre très actif
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 176
    Par défaut
    si tu veux bénéficier du polymorphisme, il faut que tu créé un (ou mieux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vector<unique_ptr<Brique>>
    . Avec vector<Brique>, tu n'auras que des briques de base.

  3. #3
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 633
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 633
    Par défaut
    Salut,

    On n'hérite jamais publiquement des collections de la S(T)L!!!:
    Leur destructeur n'est pas virtuel, et, de toutes manières, le type représenté par std::list<UnType> et celui représenté par std::list<UnAutreType> ne font absolument pas partie de la même hiérarchie de classes, meme si UnAutreType hérite de UnType.

    Finalement, la seule chose que ces deux types partagent, c'est une interface fort semblable, bien qu'adaptée au type que la liste doit contenir

    En outre, du point de vue conceptuel, Mobiles_liste n'est pas une liste, mais elle est "implémentée comme" une liste. Et c'est typiquement le genre de détails qui n'intéresse que le développeur de la classe

    Si ne veux pas travailler avec un membre de type std::list<Mobile> (ce qui serait malgré tout toujours préférable), tu devrais, pour toutes ces raisons, plutôt envisager l'héritage privé.

    Mais, d'un point de vue conceptuel, il faut te dire que l'héritage est la relation la plus forte qui puisse unir deux classes, et qu'il est souvent amplement préférable d'utiliser la composition à la place ;à
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre régulier
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2013
    Messages : 6
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Salut,

    On n'hérite jamais publiquement des collections de la S(T)L!!!:
    Mais, d'un point de vue conceptuel, il faut te dire que l'héritage est la relation la plus forte qui puisse unir deux classes, et qu'il est souvent amplement préférable d'utiliser la composition à la place ;à
    Merci pour cette précision, c'était la première fois que j'osais le faire et je me demandais pourquoi je ne l'avais pas fait avant (maintenant je sais)
    J'ai pris en compte vos remarques et j'ai ajouté une classe Brique_gene dont hérite mes deux types de brique avec une fonction virtuelle "afficher".
    Non seulement c'est plus cohérent mais ça fonctionne.

    Bon maintenant les fuites mémoires ...

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 633
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 633
    Par défaut
    Citation Envoyé par beuted Voir le message
    Bon maintenant les fuites mémoires ...
    Pour cela:

    Soit tu peux utiliser les pointeurs intelligents (unique_ptr, shared_ptr, weak_ptr) de C++11 ou de boost, soit tu dois veiller à respecter scrupuleusement le principe de la responsabilité unique:

    Il ne devrait y avoir qu'un seul endroit où tes différents éléments sont effectivement détruits, après que tu te sois, évidement, assuré qu'ils ne sont plus référencés nulle part
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

Discussions similaires

  1. Constructeur par copie et std::list
    Par Captain_JS dans le forum SL & STL
    Réponses: 5
    Dernier message: 13/12/2005, 19h15
  2. [C++][std::list] Reinterpret cast
    Par chronos dans le forum SL & STL
    Réponses: 7
    Dernier message: 18/08/2005, 17h04
  3. [dev-C++]std::list<tree_node<T>*> iterator;
    Par jmv dans le forum Dev-C++
    Réponses: 7
    Dernier message: 06/05/2005, 13h14
  4. acceder au n iéme element d'une liste std::list
    Par sorari dans le forum SL & STL
    Réponses: 4
    Dernier message: 23/03/2005, 15h21
  5. [std::list][find_if] problème avec mes foncteurs
    Par n!co dans le forum SL & STL
    Réponses: 12
    Dernier message: 04/02/2005, 11h56

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