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 :

méthode virtuelle dans héritages


Sujet :

Langage C++

  1. #1
    Membre averti
    Homme Profil pro
    Freelance
    Inscrit en
    Février 2008
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : Février 2008
    Messages : 312
    Points : 390
    Points
    390
    Par défaut méthode virtuelle dans héritages
    bonjour à tous
    voila je débute en c++ et je suis actuellement en train de faire un petit jeu d'échec avec qt
    j'en suis à la définition des classes et je rencontre déja un problème
    j'ai une classe pièces et 7 classes pion, cavalier,... qui dérive de celle ci
    toutes les données sont contenus dans pièces, les sous-classes n'ont pas de propriété spécifiques. Ce qui est spécifique aux sous-classes est la méthode déplacer(). j'ai donc déclaré dans piece la méthode deplacer() comme virtual.
    J'ai aussi déclaré le destructeur comme virtual, comme indiqué sur le site (ou un autre je sais plus.
    avant de vous montrer le code je vous montre tous les warnings et erreurs que ca me provoque:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    //warning
    undefined reference to `tour::~tour()'
    undefined reference to `tour::~tour()'
    undefined reference to `vtable for pieces'
    //des undefined comme ca y en a 80
    //1 erreur
    :-1: error: collect2: ld returned 1 exit status
    maintenant le code de la sur classe
    pieces.h
    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
     
    #ifndef PIECE_H
    #define PIECE_H
    #include "cases.h"
    #include <QString>
    #include <QIcon>
     
     
    class pieces
    {
    public:
        pieces(int j, int w, int z);
        int getnomjoueur();
        virtual QString deplacer(cases *c);
        QIcon geticone();
        void seticon(QIcon ic);
        int getx();
        int gety();
        virtual ~pieces();
     
    protected:
        QIcon icone;
        int nomJoueur;
        int x;
        int y;
    };
     
    #endif // PIECE_H
    pieces.cpp
    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
     
    #include "pieces.h"
    //l'icone n'est pas renseigné dans le constructeur car il résulte d'un test dasn la sous-clase
    //cette icone n'est donc pas connu lors de l'appel au constructeur de pièces
    pieces::pieces(int j,int w, int z)
    {
        nomJoueur = j;
        x=w;
        y=z;
    }
     
    QIcon pieces::geticone(){return icone;}
    int pieces::getnomjoueur() {return nomJoueur;}
    int pieces::getx(){return x;}
    int pieces::gety(){return y;}
    et un exemple d'une sous-classe
    cavalier.h
    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
     
    #ifndef CAVALIER_H
    #define CAVALIER_H
     
    #include <QString>
    #include "cases.h"
    #include "pieces.h"
     
    class cavalier:public pieces
    {
    public:
        cavalier(int j, int w, int z);
        QString deplacer(cases *c);
        ~cavalier();
    };
     
    #endif // CAVALIER_H
    cavalier.cpp
    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
     
    #include "cavalier.h"
     
    cavalier::cavalier(int j,int w, int z):pieces(j,w,z)
    {
        QString i;
        if (j==1) i="image/cavb.png";
        else i="image/cavn.png";
        //icone est une propriete de pieces, peut etre que je n'ai pas le droit???
        icone=QIcon(i);
    }
     
    QString cavalier::deplacer(cases *c)
    {
        return "";
    }
    voila je sais plus trop quoi faire, je suis un peu paumé dans mon héritage, j'ai un peu tout essayé, virtual pas virtual, déclarer le constructeur dans le cpp pas le déclarer,... merci d'avance pour vos réponses

  2. #2
    Membre actif
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2004
    Messages
    230
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2004
    Messages : 230
    Points : 250
    Points
    250
    Par défaut
    tu as oublie le destructeur de ta classe Tour ainsi que l'implementation de celui de piece

  3. #3
    Membre averti
    Homme Profil pro
    Freelance
    Inscrit en
    Février 2008
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : Février 2008
    Messages : 312
    Points : 390
    Points
    390
    Par défaut
    bonjour,
    concernant la table pieces en effet j'ai oublié d'implémenter le destructeur ainsi que dans cavalier
    Cavalier n'est qu'un exemple toutes mes autres sous-classes sont comme ca. J'ai nettoyé un peu mon code j'avait quelques petites erreurs par ci par la
    (oubli d'implémentation du destructeur dans les sous-classes, #includes cases enlevé des sous-classes,...) je me retrouve avec 6 warnings et 1 erreur
    undefined reference to `pieces::~pieces()'
    undefined reference to `pieces::~pieces()'
    undefined reference to `pieces::~pieces()'
    undefined reference to `pieces::~pieces()'
    undefined reference to `pieces::~pieces()'
    undefined reference to `pieces::~pieces()'
    :-1: error: collect2: ld returned 1 exit status

    A savoir que j'ai une référence circulaire entre cases et pieces, j'ai donc un class pieces; dans cases.h et #include'pieces.h' dans cases.cpp, et un simple #include 'cases.h' dans pieces.h. j'ai l'impression que c'est cette référence circulaire qui provoque toute ces erreurs

  4. #4
    Membre averti
    Homme Profil pro
    Freelance
    Inscrit en
    Février 2008
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : Février 2008
    Messages : 312
    Points : 390
    Points
    390
    Par défaut
    bon sujet résolu
    je poste la solution si ca peut aider quelqu'un

    méthode virtuel dans une sur classe
    sur classe.h
    mettre virtual devant la méthode virtuelle
    mettre aussi le destructeur en virtual
    surclasse.cpp
    implémenter la méthode virtuelle(ainsi que le destructeur), même si elles sont vides mais ne pas mettre virtual devant

    dans la sous-classe
    sous classe.h
    mettre la méthode et le destructeur sans le mot clé virtual
    sous classe.cpp
    implémenter la méthode et le destructeur

    si il y a des références à d'autres classes dans la sur classe et les sous-classes, inclure les références seulement dans la sur classe (sauf si la référence est seulement dans la sous-classe)

    voila je crois que j'ai fait le tour si j'ai dit des conneries n'hésitez pas à me corriger

  5. #5
    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
    Salut,
    Outre les problèmes de destructeurs non définis, tu peux avoir des erreurs de link avec gcc si toutes tes fonctions non virtuelles sont définies inline. Cf ce post et celui-ci.
    Citation Envoyé par bobby51 Voir le message
    méthode virtuel dans une sur classe
    sur classe.h
    mettre virtual devant la méthode virtuelle
    mettre aussi le destructeur en virtual
    Pour le destructreur, c'est un peu plus subtil : le destructeur doit être virtuel s'il est public et protégé s'il n'est pas virtuel. Tu peux choisir un cas ou l'autre selon que tu souhaites une destruction de ton objet à partir de sa classe de base ou non.
    Citation Envoyé par bobby51 Voir le message
    surclasse.cpp
    implémenter la méthode virtuelle(ainsi que le destructeur), même si elles sont vides mais ne pas mettre virtual devant
    virtual s'utilise dans la classe jamais dans la définition de la fonction à l'extérieur de la classe.
    Citation Envoyé par bobby51 Voir le message
    dans la sous-classe
    sous classe.h
    mettre la méthode et le destructeur sans le mot clé virtual
    Je recommande exactement le contraire : mettre virtual dans les classes dérivées pour les fonctions virtuelles de la classe de base pour ne pas créer d'ambigüité.
    Citation Envoyé par bobby51 Voir le message
    si il y a des références à d'autres classes dans la sur classe et les sous-classes, inclure les références seulement dans la sur classe (sauf si la référence est seulement dans la sous-classe)
    Les associations vers d'autres classes doivent se faire là où la conception a déterminé que la relation était pertinente : dans la classe de base ou la classe dérivée selon ce qu'on veut lier ! Cela n'a rien à voir avec l'héritage et les fonctions virtuelles.

    Pour plus d'info sur les fonctions virtuelles : Les fonctions virtuelles en C++, par votre serviteur.


    Sinon, concernant ton problème, si la seule variation est vraiment sur le déplacer, je n'aurais pas fait une classe pièce de laquelle dérive une classe tour, cavalier, fou, reine, roi et pion. J'aurais probablement utilisé une seule classe pièce avec un Design Pattern Stratégie pour le déplacement. L'idée est de n'avoir qu'un seul type d'objet, pièce, et d'isoler la variabilité du déplacement dans une classe dédiée.

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

Discussions similaires

  1. Heritage et méthode virtuelle dans constructeur
    Par nspxroronoa dans le forum C++
    Réponses: 14
    Dernier message: 01/12/2011, 10h49
  2. Réponses: 6
    Dernier message: 10/10/2007, 20h11
  3. Réponses: 15
    Dernier message: 05/07/2007, 01h29
  4. Réponses: 2
    Dernier message: 10/05/2007, 17h29
  5. Exceptions, héritage et méthodes virtuelles
    Par Nuwanda dans le forum C++
    Réponses: 13
    Dernier message: 23/05/2006, 12h06

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