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 :

Problème avec l'heritage virtuel


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Problème avec l'heritage virtuel
    Bonjour !
    Je me noie un peu dans l'heritage, pouvez vous m'aider ?
    J'explique mon probleme :
    J'ai une classe A
    Puis une classe B qui hérite de A
    Puis une classe C qui herite de A
    et enfin une classe D qui herite de B et C
    Si j'ai bien tout suivi, il faut que je declare B et C en heritage virtuel sinon j'aurais deux A dans mes objets D, c'est ça ?
    Donc j'ai fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class B : virtual public A
    {
    ...
    }
    class C : virtual public A
    {
    ...
    }
    Ca marche.
    Maintenant je manipule des B*, des C* et des D* en tant que A* (je manipule une liste contenant des A*)
    J'ai compris qu'il fallait des fonctions virtuelles pour mes affichages par exemple, tout ça ça marche bien.
    Là où ça marche pas, c'est quand je veux utiliser une methode de B ou de C. J'ai par exemple une methode publique fb() dans ma classe B
    et mon pointeur A* pa
    si j'appelle pa->fb() le compilo me dit que la fonction n'est pas déclarée
    alors j'essaye un
    ((B*)pa)->fb()
    et il me dit : cannot convert from base `A' to derived type `B' via virtual base `A'
    donc il peut pas car c'est un heritage virtuel ?
    Alors comment je fais ?
    Merci d'avance pour vos réponses.

  2. #2
    Membre averti

    Inscrit en
    Juillet 2008
    Messages
    186
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 186
    Points : 350
    Points
    350
    Par défaut
    Bonjour,

    Non. Tu ne peux pas.

    La seule solution, c'est de déclarer la fonction membre de la classe B comme virtuelle pure dans la classe A.

    Didier

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Merci beaucoup !

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Bonjour et bienvenu,
    dynamic_cast? Cependant lire ça, mais surtout ça.
    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
     
    class A
    {
    public:
       void fn_A()
       {
          std::cout<<"A"<<std::endl;
       }
       virtual void cestqui()
       {
          std::cout<<"c'est A"<<std::endl;
       }
    };
     
    class B: virtual public A
    {
    public:
       void fn_B()
       {
          std::cout<<"B"<<std::endl;
       }
       virtual void cestqui()
       {
          std::cout<<"c'est B"<<std::endl;
       }
    };
     
    class C: virtual public A
    {
    public:
       void fn_C()
       {
          std::cout<<"C"<<std::endl;
       }
       virtual void cestqui()
       {
          std::cout<<"c'est C"<<std::endl;
       }
    };
     
    class D: public B, public C
    {
    public:
       void fn_D()
       {
          std::cout<<"D"<<std::endl;
       }
       virtual void cestqui()
       {
          std::cout<<"c'est D"<<std::endl;
       }
    };
     
    void Fonction(A*p_a)
    {
       p_a->cestqui();
       if(dynamic_cast<D*>(p_a)){
          dynamic_cast<D*>(p_a)->fn_D();
       }
       else
       if(dynamic_cast<B*>(p_a)){
          dynamic_cast<B*>(p_a)->fn_B();
       }
       else
       if(dynamic_cast<C*>(p_a)){
          dynamic_cast<C*>(p_a)->fn_C();
       }
       else{
          p_a->fn_A();
       }
    }
     
     
    int main()
    {
       A a;
       B b;
       C c;
       D d;
       Fonction(&a);
       Fonction(&b);
       Fonction(&c);
       Fonction(&d);
       return getchar();
    }

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut, et bienvenue sur le forum.

    Déjà, il serait sans doute intéressant de se poser la question de savoir s'il est vraiment nécessaire de la classe D dans ton exemple hérite des classes B et C...

    En effet, il faut toujours se rappeler que l'héritage est la relation la plus forte qui puisse exister entre deux classe: c'est la relation qui permet - d'un point de vue sémantique - de dire que la classe enfant est un objet de la classe parent.

    Il faudrait donc voir quelles sont les classes réellement créées, mais tu te rend bien compte que les cas où une classe doit hériter de plusieurs types sont donc déjà *relativement* rares, et que les cas où il se fait que ces différents types doivent hériter d'une classe identiques deviennent... l'exception à une exception.

    Je ne dis absolument pas qu'il faut renoncer à l'héritage multiple et / ou à l'héritage virtuel, je dis - simplement - qu'il faut veiller à ce qu'il soit réellement nécessaire

    Si donc tu pouvais nous donner quelques explications supplémentaires sur l'implémentation réelle, nous pourrions peut être en arriver à te dire si tu te trouve dans un cas où l'héritage multiple virtuel est réellement la meilleure solution
    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

Discussions similaires

  1. Problème avec l'heritage de dict
    Par ernestrenan dans le forum Général Python
    Réponses: 7
    Dernier message: 02/08/2011, 22h00
  2. Réponses: 3
    Dernier message: 31/07/2007, 16h40
  3. Problème avec une méthode virtuelle pure
    Par Burckel dans le forum C++
    Réponses: 4
    Dernier message: 05/12/2006, 13h00
  4. Réponses: 8
    Dernier message: 16/10/2006, 12h28
  5. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

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