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 :

Impossible d'implémenter une classe abstraite alors que les méthodes abstraites sont implémentées


Sujet :

Langage C++

  1. #1
    Membre habitué Avatar de touftouf57
    Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2007
    Messages : 362
    Points : 174
    Points
    174
    Par défaut Impossible d'implémenter une classe abstraite alors que les méthodes abstraites sont implémentées
    Bonjour à tous, et bonnes fêtes de fin d'année.

    Bon j'ai un souci, sous visual studio 2008 en C++.

    Voila j'ai créé une "interface" Deplacable qui contient une seule méthode:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual void deplacer(int x, int y)=0;
    Vu quelle est virtuelle pure, c'est pour ça que j'ai défini cette classe comme une interface. Bref j'ai une classe ObjetAnime qui hérite de Deplacable et qui implémente donc la méthode deplacer(int x, int y).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void ObjetAnime::deplacer(int x, int y){//déplacement relatif
    	setX(getX()+x);
    	setY(getY()+y);
    }
    Maintenant j'ai une classe abstraite DeplacableHorizontal qui hérite de Deplacable:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class DeplacableHorizontal: public Deplacable{
    public:
    	DeplacableHorizontal(short vitesseH=0);
    	virtual void deplGauche();
    	virtual void deplDroite();
    ...
    et voici leurs implémentations
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void DeplacableHorizontal::deplGauche(){
    	deplacer(-_vitesseH,0);
    }
     
    void DeplacableHorizontal::deplDroite(){
    	deplacer(_vitesseH,0);
    }
    Et c'est maintenant que le problème arrive. J'ai une classe Missile qui hérite de ObjetAnime et de DeplacableHorizontal.
    Et à la compil, je me prend une erreur C2259: "Missile": impossible d'instancier une classe abstraite à cause des membres suivants:
    'void Deplacable::deplacer(int,int)' est abstrait


    Pourtant deplacer est défini dans la classe ObjetAnime.
    Faut-il absolument écrire dans le Missile.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual void deplacer(int x, int y);
    pour que cela fonctionne, même si on ne l'implémente pas dans le cpp?
    Je trouve cela un peu tordu de redéfinir des méthodes qui le sont déjà.

  2. #2
    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,
    Si je reprends ta description tu as comme héritage :
    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
    struct Deplacable
    {
       virtual void deplace()=0;
       virtual ~Deplacable(){}
    };
     
    struct ObjetAnime : public Deplacable
    {
       virtual void deplace(){std::cout<<"objetAnime\n";}
    };
     
    struct DeplacableHorizontal : public Deplacable
    {
       virtual void deplGauche(){deplace();}
    };
     
    struct MonMissile : public DeplacableHorizontal, public ObjetAnime
    {
    };
    MonMissile hérite 2 fois de la classe Deplacable :
    => Une fois via l'héritage DeplacableHorizontal => Deplacable
    => Une fois via l'héritage ObjetAnime => Deplacable

    Or, seule une branche spécialise la fonction abstraite (ObjectAnime). D'où ton erreur.

    La solution : passer par l'héritage virtuel (F.A.Q Qu'est-ce que l'héritage virtuel et quelle est son utilité ?)

    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
    struct Deplacable
    {
       virtual void deplace()=0;
       virtual ~Deplacable(){}
    };
     
    struct ObjetAnime : public virtual Deplacable
    {
       virtual void deplace(){std::cout<<"objetAnime\n";}
    };
     
    struct DeplacableHorizontal : public virtual Deplacable
    {
       virtual void deplGauche(){deplace();}
    };
     
    struct MonMissile : public DeplacableHorizontal, public ObjetAnime
    {
    };
    Voir aussi : Les fonctions virtuelles en C++.

  3. #3
    Membre habitué Avatar de touftouf57
    Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2007
    Messages : 362
    Points : 174
    Points
    174
    Par défaut
    Merci beaucoup,
    C'est une partie du cours que l'on a pas étudié volontairement, le prof nous a conseillé de lire cette partie une fois qu'on aurait un peu plus de bouteille en C++.

    J'ai cette configuration (héritage en diamant) dans plusieurs endroits de mon projet.
    Puisque je ne veux jamais de doublon dans ce projet, serait-il judicieux de toujours faire de l'héritage virtuel?

    En tout cas merci.

  4. #4
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par touftouf57 Voir le message
    Merci beaucoup,
    C'est une partie du cours que l'on a pas étudié volontairement, le prof nous a conseillé de lire cette partie une fois qu'on aurait un peu plus de bouteille en C++.

    J'ai cette configuration (héritage en diamant) dans plusieurs endroits de mon projet.
    Puisque je ne veux jamais de doublon dans ce projet, serait-il judicieux de toujours faire de l'héritage virtuel?

    En tout cas merci.
    Toujours ? Diable non !

    Par contre, tu peux te demander si l'héritage est bien la solution à employer dans chaque cas. Il existe des règles à respecter sur le sujet qui vont bien plus loin que la relation informelle "est un".
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  5. #5
    Membre habitué Avatar de touftouf57
    Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2007
    Messages
    362
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2007
    Messages : 362
    Points : 174
    Points
    174
    Par défaut
    Bonjour Emmanuel Deloget

    Le "toujours" fait référence uniquement à ce projet.
    Il existe des règles à respecter sur le sujet qui vont bien plus loin que la relation informelle "est un".
    Tu fais référence au design pattern strategy? Si c'est le cas je ne vois pas vraiment comment l'implémenter ici.

  6. #6
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par touftouf57 Voir le message
    Bonjour Emmanuel Deloget

    Le "toujours" fait référence uniquement à ce projet.
    Le smiley fait référence à une moquerie gentille Je me doutais bien que le terme utilisé n'avait pas vocation à étendre la solution à tous les héritages dans tous les programmes du monde

    Ceci dit, même dans ton projet, c'est trop : l'héritage virtuel est lourd, et complexe à débugger. Si tu ne veux pas avoir de surprise, utilise le que lorsque c'est nécessaire. C'est un conseil d'ami

    Citation Envoyé par touftouf57 Voir le message
    Tu fais référence au design pattern strategy? Si c'est le cas je ne vois pas vraiment comment l'implémenter ici.
    Non, je fais référence au fait que la relation d'héritage ne doit exister que si elle ne viole pas un principe de POO nommé Principe de Substitution de Liskov. Il y a déjà eu pas mal de discussion sur ce sujet sur developpez.net, je t'encourage donc à chercher sur le forum (Liskov, ou LSP (pour Liskov Substitution Principle).

    (et pour le design pattern, ça serait plutot le DP composite que le DP strategy ; composite est un DP structurel qui donne une indication sur comment architecturer le code, tandis que strategy est un DP comportemental qui dépends de l'architecture mise en place).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

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

Discussions similaires

  1. Implémenter une classe en tant que source de données
    Par BasicZX81 dans le forum VB.NET
    Réponses: 3
    Dernier message: 06/10/2013, 14h42
  2. Réponses: 3
    Dernier message: 02/07/2013, 09h04
  3. Erreur: Impossible d'instancier une classe abstraite
    Par petitnul12 dans le forum C++
    Réponses: 2
    Dernier message: 16/11/2012, 23h39
  4. Réponses: 0
    Dernier message: 09/11/2010, 11h01
  5. Réponses: 3
    Dernier message: 30/10/2007, 15h14

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