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 :

vecteur héritage c++


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Technicien, en informatique
    Inscrit en
    Décembre 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Technicien, en informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 17
    Par défaut vecteur héritage c++
    Bonjour,

    Je vais expliquer mon problème par un exemple.

    J'ai 4 class, une class mère, une class fils1, une class fils2 et une class3

    les class fils héritent de class mère.

    Dans mon main j'ai un vecteur (vecteur <mere*>), donc lors d'un nouveau class1, class2 ou class3 je le place dans ce vecteur.

    Ce que je voudrais savoir c'est s'il y a un moyen de savoir lorsque je manipule les class qui se trouvent dans mon vecteur, qu'elle class je manipule ou est-ce que je dois ajouter un attribut en plus.

    Merci pour votre aide.

  2. #2
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Non, tu peux pas savoir.
    Une bonne question, c'est "pourquoi tu veux savoir ?"
    Sinon une solution qui marche c'est un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class Base
    {
         virtual const std::string GetTypeName const () = 0;
    };
    Tu fais hériter tes classes de Base, et dans tes classes tu redéfinis la méthode GetTypeName :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class Mere : public Base
    {
         virtual const std::string GetTypeName const () {return "Mere";}
    };
    Tu peux faire une macro pour automatiser ça...

  3. #3
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Mias surtout, répond d'abord à la question importante: Pourquoi en ai-je besoin?
    C'est à dire:
    Pourquoi mettrai-je des choses différentes dans le même tas, si c'est pour les traiter différemment?
    Il y a deux façons de réfléchir à ce problème:
    • N'aurai-je pas du faire plusieurs tas? c'est à dire utiliser plusieurs vecteurs
    • Ne puis-je pas faire en sorte d'agir de la même façon? utiliser l'héritage et la virtualité permet d'avoir des réactions différentes à une même stimulation

  4. #4
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Citation Envoyé par hbenji Voir le message
    Ce que je voudrais savoir c'est s'il y a un moyen de savoir lorsque je manipule les class qui se trouvent dans mon vecteur, qu'elle class je manipule ou est-ce que je dois ajouter un attribut en plus.
    Bonjour,

    Tu peux récupérer le type à l'aide du pattern visiteur, ça donne quelque chose du genre :
    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
    struct Visitor {
    	void operator()(Class1& c) { /* code spécifique à Class1 */ }
    	void operator()(Class2& c) { /* code spécifique à Class2 */ }
    };
     
    struct Mere {
    	...	
    	virtual void accept(V& visitor) = 0;
    }
     
    struct Class1 {
    	...
    	virtual void accept(V& visitor) { v(*this); }
    }
     
    struct Class2 {
    	...
    	virtual void accept(V& visitor) { v(*this); }
    }
     
    std::vector<Mere*> vec;
    ...
    Visitor v;
    for(auto ptr: vec) {
    	ptr->accept(v);
    }
    Citation Envoyé par leternel Voir le message
    Pourquoi mettrai-je des choses différentes dans le même tas, si c'est pour les traiter différemment?
    Il arrive de devoir faire une opération a() sur tous les éléments, et une opération b() seulement sur un seul type par exemple. Mais effectivement, la question est à se poser.

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Iradrille Voir le message
    Il arrive de devoir faire une opération a() sur tous les éléments, et une opération b() seulement sur un seul type par exemple. Mais effectivement, la question est à se poser.
    Dans ce cas, pourquoi de l'héritage ?
    Si l'on doit réaliser un traitement différent, que l'on ne peut factoriser dans les services ou comportements de la classe, l'héritage est superflu non non avenu.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Je suis tout à fait en désaccord.

    Cela signifierait que les classes filles ne peuvent offrir que les services offerts par la classe mère, et ne peuvent définir aucune autre nouvelle fonction. C'est une curieuse conception de la programmation objet.

    Ce sur quoi on peut s'interroger, c'est sur la pertinence de tout mettre dans un seul vecteur.

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

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    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 290
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Dans ce cas, pourquoi de l'héritage ?
    Si l'on doit réaliser un traitement différent, que l'on ne peut factoriser dans les services ou comportements de la classe, l'héritage est superflu non non avenu.
    Je plussoie.
    C'est décidément un problème à la mode ces temps-ci.
    Pourquoi vouloir faire une hiérarchie de classe si chaque classe a un protocole différent? ça ne fait que rajouter des complications et ça n'apporte rien.
    C'est comme les templates; parfois je vois du code où on voit clairement que le développeur à voulu absolument utiliser des templates alors que ça n'apporte que, dans le meilleur des cas, de la complexité au code.

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

    Informations professionnelles :
    Activité : aucun

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

    De manière générale, tu peux (comprends: il est tout à fait légal de le faire ) envisager de fournir une méthode qui permet de récupérer le type réel de ton pointeur et de travailler à coup de dynamic_cast.

    Cela pourrait prendre la forme de
    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
    enum ClassType
    {
        fils1,
        fils2,
        fils3
    };
    class Mere
    {
        public:
            virtual ClassType type() const = 0;
    };
    class Fils1 : public Mere
    {
        public:
            virtual ClassType type() const {return fils1;}
    };
    class Fils2 : public Mere
    {
        public:
            virtual ClassType type() const {return fils2;}
    };
    class Fils3 : public Mere
    {
        public:
            virtual ClassType type() const {return fils3;}
    };
     
    int main()
    {
        std::vector<Mere*> tab;
        /* ... */
        for(auto it : tab)
        {
            switch(it->type())
            {
                case fils1:
                    Fils1 * temp= dynamic_cast<Fils1*>(it);
                    /* ... */
                    break;
                case fils1:
                    Fils2 * temp= dynamic_cast<Fils2*>(it);
                    /* ... */
                    break;
                case fils1:
                    Fils3 * temp= dynamic_cast<Fils3*>(it);
                    /* ... */
                    break;
            }
        }
    }
    Mais je te déconseille très fortement et avec la plus grand insistance de faire de la sorte

    En effet, si tu choisis cette option, tu vas très rapidement te retrouver dans une situation dans laquelle tu passeras ton temps à tester le type réel de tes objets (ou plutôt de tes pointeurs ou de tes références) avant de les transtyper afin de pouvoir les utiliser.

    Cela va mener à une complexification systématique et largement inutile de ton code et cela va présenter un inconvénient majeur:

    Si tu décides, un jour, de rajouter une classe dérivée (et les raisons pour le faire sont nombreuses, la question n'est donc pas de savoir SI tu voudras le faire, mais bien QUAND tu voudras le faire ), tu devras reprendre systématiquement tout ton code pour prendre cette nouvelle classe en compte

    L'idéal est donc de se baser sur le principe du double dispatch:

    L'idée est de se dire que les pointeurs connaissent leur type réel.

    Il est donc possible d'envisager un comportement que l'on appellera au départ de "tout objet passant pour être du type de base" qui s'adaptera au type réel de l'objet.

    Le principe du visiteur se base sur un principe similaire
    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

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par hbenji Voir le message
    Ce que je voudrais savoir c'est s'il y a un moyen de savoir lorsque je manipule les class qui se trouvent dans mon vecteur, qu'elle class je manipule ou est-ce que je dois ajouter un attribut en plus.
    Il y a la solution du dynamic_cast, qui n'est généralement pas des plus heureuses.

  10. #10
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Citation Envoyé par oodini Voir le message
    Il y a la solution du dynamic_cast, qui n'est généralement pas des plus heureuses.
    C'est vrai c'est pas toujours heureux mais il y a parfois des cas où c'est une bonne solution.

Discussions similaires

  1. Héritage dans vecteurs
    Par XecK_4000 dans le forum C++
    Réponses: 3
    Dernier message: 23/02/2015, 17h22
  2. Vecteur et héritage
    Par kovax dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 20/06/2009, 09h14
  3. Héritage, vecteurs, problème de type
    Par Pascmar dans le forum C++
    Réponses: 3
    Dernier message: 29/10/2007, 16h16
  4. Problème héritage et vecteur
    Par scrat88 dans le forum Langage
    Réponses: 10
    Dernier message: 23/05/2007, 18h02
  5. Héritage entre Forms
    Par BarBal dans le forum Composants VCL
    Réponses: 7
    Dernier message: 29/08/2002, 17h44

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