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 :

Classe abstraite et héritage


Sujet :

Langage C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    121
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 121
    Par défaut Classe abstraite et héritage
    Bonjour tout le monde,

    J'ai un soucis avec une classe abstraite.
    J'ai 3 classes :
    - Arbre
    - ArbreEquilibre qui dérive d'Arbre
    - QuadTree qui dérive d'ArbreEquilibre

    ArbreEquilibre est une classe qui possède une méthode virtuelle pure (ce qui entraine qu'elle peut être considérée abstraite si j'ai bien suivi).
    Dans le fichier ArbreEquilibre.hpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual bool estEquilibre()=0;
    Le constructeur d'Arbre est de la forme suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Arbre::Arbre(char* chemin) {
    ...
    }
    Le constructeur d'ArbreEquilibre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ArbreEquilibre::ArbreEquilibre(char *fichier) : Arbre(fichier){}
    Le constructeur de QuadTree :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    QuadTree::QuadTree(char* fichier) : ArbreEquilibre(fichier){}

    Le problème est que j'ai une erreur à la compilation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    quadtree.cpp:10: undefined reference to `ArbreEquilibre::ArbreEquilibre(char*)'

    Je n'arrive pas à trouver d'où viens le problème, comme cela marche avec toutes mes autres classes, je suppose que cela vient du fait que ArbreEquilibre est une classe abstraite.
    Elle ne devrait alors peut être pas avoir de constructeur mais comment appeler le constructeur d'Arbre dans QuadTree dans ce cas ?

    Merci d'avance !

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    327
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 327
    Par défaut
    Bonjour,
    Je pense que tu as un problème dans la conception de ton programme car un classe abstraite ne peut pas être instancié.
    C'est pour cela qu'il y a une erreur au niveau du constructeur.
    A bientôt

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 109
    Par défaut
    Essaie de voir ceci :
    - As tu bien pensé à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    class ArbreEquilibre : public Arbre
    class QuadTee : public ArbreEquilibre
    - Redefinir ta fonction virtuelle dans les autres classes dérivées.

    - Et en effet, tu ne pourras pas écrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Arbre* pArbre = new Arbre(...)
    (Les constructeurs semblent justes)

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    121
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 121
    Par défaut
    Merci pour vos réponses.

    @Kaktus : Oui l'héritage est bien défini et la fonction estEquilibre est bien redéfinie dans QuadTree.
    Par contre pourquoi ne pourrais-je pas mettre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Arbre* pArbre = new Arbre(...)
    ?

    @wakan : Je croyais qu'une classe B qui hérite d'une classe A devait nécessairement appeler un constructeur de A dans son constructeur.
    Si une classe hérite d'une classe abstraite, comment dois-je préciser le constructeur de cette classe par rapport au constructeur de la classe abstraite ?
    (ie ; comment dois-je définir le constructeur de QuadTree par rapport à celui de ArbreEquilibre si ArbreEquilibre ne doit pas posséder de constructeur ?)

    Si je ne précise rien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QuadTree::QuadTree(char* fichier){}
    J'ai l'erreur suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    quadtree.cpp:10: erreur: no matching function for call to ‘ArbreEquilibre::ArbreEquilibre()’
    arbreequilibre.hpp:26: note: candidats sont: ArbreEquilibre::ArbreEquilibre(char*)
    arbreequilibre.hpp:19: note:                 ArbreEquilibre::ArbreEquilibre(const ArbreEquilibre&)

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

    Informations professionnelles :
    Activité : aucun

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

    Une classe dérivée doit appeler le constructeur de sa classe de base si la classe de base ne dispose pas d'un constructeur par défaut...

    Mais, il me semble déjà t'avoir fait la remarque que, pour pouvoir t'aider plus efficacement, il est préférable de nous fournir un code minimum compilable qui reproduise le problème (si je ne te l'ai pas encore faite, je te présente mes excuses pour le ton un peu "agressif", mais... prend la remarque en compte )

    A vrai dire, il est rare qu'une classe dérivée d'une classe concrète soit elle-même une classe abstraite, et c'est sans doute en partant de ce principe que Kaktus a estimé, peut être à tord, que, si ArbreEquilibre est abstraite, Arbre l'est également, ce qui justifie sa remarque sur l'impossibilité d'allouer dynamiquement la mémoire pour un objet de type Arbre ...

    Ci se n'est pas le cas, cela sent bien souvent assez fort le problème de conception
    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

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 109
    Par défaut
    Ta classe "Arbre" est virtuelle pure, tu l'a précisé. Tu ne peux pas l'instancier, donc pas de new Arbre(...).
    Les classes virtuelles servent d'interface en général et portent des noms souvent généraux style "vehicule", "objet" etc...
    C'est logique, tu ne peux pas te représenter un véhicule (c'est quoi ? un avion ? un bateau ? un robot ?) donc pas l'instancier.

    Par contre, tu peux avoir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Arbre* monArbre = new ArbreEquilibre(...)
    Arbre* monArbreSpecigfique = new QuadTree(...)

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    121
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 121
    Par défaut
    Hmm daccord...

    @Kaktus : C'est ArbreEquilibre qui est une classe abstraite, Arbre est une classe concrète.
    ArbreEquilibre tout comme véhicule est une appellation générique pour tous les arbres qui comportent un critère d'équilibre.
    Je peux en effet créer une instance d'Arbre qui n'aura aucune particularité si ce n'est qu'elle correspond aux critères de définition des arbres.
    Je ne peux cependant pas créer d'instance d'ArbreEquilibre car il faut pour cela avoir spécifier le critère d'équilibre correspondant (ce qui serait fait dans les classes dérivées d'ArbreEquilibre telle que QuadTree, dans cette classe chacun des noeud ne peut pas avoir plus de 4 fils).


    @koala01 : Désolé de ne pas avoir mis de code compilable, c'est vrai que ça doit être plus confortable pour commenter ou corriger.

    Tu dit qu'il est rare qu'une classe dérivée d'une classe concrète soit abstraite. Je vais exposer ma situation, je veux bien que vous me disiez si dans ce cas cela semble justifié ou s'il vaudrait mieux faire autrement.

    L'idée est que j'écris un programme qui devra permettre de gérer différents types d'arbres.

    Parmis ces types d'arbres, certains sont équilibrés et d'autres non. Ceux qui sont équilibrés doivent satifairent un critère d'équilibre. J'avais donc pensé faire une classe abstraite ArbreEquilibre qui contienne une méthode virtuelle estEquilibre que devraient redéfinir tous les types d'arbres qui sont équilibrés.

    Ce n'est pas la meilleure façon de s'y prendre ?


    Voici un extrait compilable du code qui résume se problème :

    arbre.hpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #ifndef _ARBRE_H
    #define	_ARBRE_H
     
    class Arbre{
     
          public :
                 Arbre(char *);
    };
    #endif	/* _ARBRE_H */
    arbre.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #include "arbre.hpp"
     
    Arbre::Arbre(char* chemin) {}
    arbreequilibre.hpp
    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
    #ifndef _ARBREEQUILIBRE_H
    #define	_ARBREEQUILIBRE_H
     
    #include"arbre.hpp"
     
    class ArbreEquilibre : public Arbre {
     
    public:
     
        ArbreEquilibre(char *);
     
        virtual bool estEquilibre()=0;
    };
     
    #endif	/* _ARBREEQUILIBRE_H */
    arbreequilibre.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include "arbreequilibre.hpp"
     
    ArbreEquilibre::ArbreEquilibre(char *fichier) : Arbre(fichier){}
     
    bool ArbreEquilibre::estEquilibre();
    quadtree.hpp
    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
    #ifndef _QUADTREE_H
    #define	_QUADTREE_H
     
    #include"arbreequilibre.hpp"
     
    class QuadTree: public ArbreEquilibre {
    private:
     
    public:
     
        QuadTree(char* fichier);
     
        bool estEquilibre();
    };
     
    #endif	/* _QUADTREE_H */
    quadtreecpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include "quadtree.hpp"
     
    QuadTree::QuadTree(char* fichier){}
     
    bool QuadTree::estEquilibre(){}
    Comment devrais-je m'y prendre ?

    PS : Comme pour mon autre poste n'hésitez pas à commenter ce qui vous semble faux ou pas propre même si ce n'est pas en rapport avec ce topic.

Discussions similaires

  1. class abstraite et héritage
    Par izissie dans le forum Langage
    Réponses: 5
    Dernier message: 13/09/2012, 17h44
  2. Réponses: 17
    Dernier message: 27/08/2007, 18h35
  3. Erreur du designer avec héritage d'une classe abstraite
    Par Xzander dans le forum Windows Forms
    Réponses: 4
    Dernier message: 04/04/2007, 00h36
  4. héritage et classes abstraites
    Par reloadead dans le forum Langage
    Réponses: 5
    Dernier message: 31/01/2007, 10h08
  5. Conception: héritage d'une classe abstraite
    Par Kikito dans le forum Langage
    Réponses: 19
    Dernier message: 05/10/2006, 17h36

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