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 :

héritages multiples et fonctions abstraites


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 31
    Par défaut héritages multiples et fonctions abstraites
    Bonjour,

    J'ai une classe B qui hérite d'une classe A.
    Ces deux classes ( des IHM en fait ) utilisent des présenteurs pA et pB. pB héritant de pA.
    Pour des raisons d'architecture, A et B ne peuvent pas connaitre pA et pB directement. J'ai donc définit deux interfaces abstraites ipA, et ipB. ipB hérite de ipA. Mes deux présenteurs héritent donc de ces deux interfaces.

    Mais quand je compile, j'ai un erreur m'indiquant que pB ne peut pas être instancié car il est abstrait à cause des fonctions abstaites de ipA.

    Ce petit exemple dvrait vous aider à comprendre:
    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
     
    #include <iostream>
    using namespace std;
     
    // Interfaces
     
    struct ipA {
       virtual void foo() = 0;
    };
     
    struct ipB : public ipA {
       virtual void bar() = 0;
    };
     
    // Présenteurs
     
    struct pA : public ipA {
       virtual void foo(){ cout << "A::foo" << endl; }
    };
     
    struct pB :  public ipB, public pA {
       //void foo(){ cout << "B::foo" << endl; }
       virtual void bar(){ cout << "B::bar" << endl; }
    };
     
    // IHM
     
    struct A {
       ipA & _p;
       A( ipA & pa ) : _p(pa){}
       void a(){ _p.foo(); }
    };
     
    struct B : public A {
       ipB & _p;
       B( ipB & pb ) : A( pb ), _p(pb){}
       void b(){ _p.bar(); }
    };
     
    // Et le main qui va bien
     
    int main() {
       pA pa; pB pb;
     
       A a(pa); B b(pb);
     
       a.a();
       b.a(); b.b();
     
       return 0;
    }
    Erreur E2352 heritage.cpp 43: Impossible de crÚer une instance de la classe abstraite 'pB' dans la fonction main()
    Erreur E2353 heritage.cpp 43: La classe 'pB' est abstraite parce que ipA::foo() = 0' dans la fonction main()
    D'où la question ultime sur la vie, l'univers et le reste : Comment faire pour mettre en place une telle architecture ?

    La seule méthode que j'ai trouvé consiste à redéfinir les méthode de ipA dans pB. Mais ce n'est pas génial.

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    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 393
    Par défaut
    Ici, le problème majeur semble ^etre qu'il considère pB comme une class abstraite, et je ne vois pas pourquoi...
    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 émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut
    Peut-être un élément de réponse ici ?

  4. #4
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    Tu as une erreur parce que ta classe pB possède 2 fonctions foo() à redéfinir : celle héritée via pA et celle héritée via ipB.
    pA a déjà redéfini foo(), mais pas ipB donc ça coince.
    En fait tu as deux "instances" séparées de ipA qui sont héritées dans un seul pB (celui de ipB et celui de pA).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    ipA  ipA
     |    |
     |    |
    ipB   pA
     \   /
      \ /
      pB
    Si j'ai bien compris tu cherches à avoir un héritage en diamant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
      ipA
      / \
     /   \
    ipB   pA
     \   /
      \ /
      pB
    Pour celà il faut passer par l'héritage virtuel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    struct ipB : public virtual ipA { 
    //...
    struct pA : public virtual ipA {
    Ton design ressemble fort à une double hiérarchie : on a 2 hiérarchies de classes qui évoluent ensembles (les interfaces et les présenteurs). Tu devrais jetter un oeil au design pattern "stairway to heaven".
    http://www.objectmentor.com/resources/articles/dih.pdf
    (partie "DUAL HIERARCHIES OF INTERFACE AND IMPLEMENTATION", mais le reste est intéressant aussi)

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 31
    Par défaut
    C'est exactement ça.
    Merci beaucoup.

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

Discussions similaires

  1. Héritage multiple et fonction virtuelle
    Par chronos dans le forum Langage
    Réponses: 5
    Dernier message: 17/02/2012, 10h15
  2. Héritage multiple et fonction virtuelle
    Par chronos dans le forum C++/CLI
    Réponses: 0
    Dernier message: 14/02/2012, 09h59
  3. Réponses: 6
    Dernier message: 12/07/2006, 19h29
  4. utilisez vous l'héritage multiple ?
    Par vodosiossbaas dans le forum C++
    Réponses: 8
    Dernier message: 13/06/2005, 20h25
  5. [XML Schemas]héritage multiple
    Par nicolas_jf dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 10/06/2003, 12h55

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