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 :

Héritage d'une classe abstraite : utilisation d'une méthode virtuelle pure avec définition par défaut


Sujet :

Langage C++

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 124
    Par défaut Héritage d'une classe abstraite : utilisation d'une méthode virtuelle pure avec définition par défaut
    Bonjour,

    je dispose d'une classe abstraite qui est héritée par 2 classes. La classe abstraite possède une méthode virtuelle pure avec une définition par défaut. Une des deux classes n'a pas la nécessitée de redéfinir la méthode virtuelle pure.

    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
    class Objet
    {
    public:
      Objet(int poid) {
        this->poid = poid;
      }
     
      virtual int getPoid() {
        return this->poid;
      }
     
      virtual int getPoidTotal() = 0 {
        return this->poid;
      };
    private:
      int poid;
    };
     
    class Fourchette : public Objet
    {
    public:
      Fourchette(int poid) : Objet(poid) {}
    };
     
    class Bouteille : public Objet
    {
    public:
      Bouteille(int poid, int poidLiquide) : Objet(poid), poidLiquide(poidLiquide) {}
     
      int getPoidTotal() {
        return this->getPoid() + this->poidLiquide;
      }
    private:
      int poidLiquide;
    };
    Le problème est que je me retrouve avec les messages d'erreurs suivant :
    - La classe Fourchette est une classe virtuelle, elle ne peut pas être
    instanciée.
    - La classe Bouteille est une classe virtuelle, elle ne peut pas être
    instanciée.

    Je suis obligé de redéfinir les méthodes virtuelles pures dans mes classes filles pour que mon code compile.

    Y a-t-il une solution pour ne pas avoir à redéfinir systématiquement mes méthodes virtuelles pures et ainsi pouvoir utiliser la définition par défaut de celles-ci ?

    Merci d'avance pour votre aide.

  2. #2
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Par défaut
    La réponse à ta question est non
    Si tu déclares une fonction virtuelle pure, tu es obligé de redéfinir la fonction dans toutes les classes dérivées, sinon tu ne pourras pas utiliser tes classes dérivées (enfin ton compilateur t'en empêchera )

    Si tu veux utiliser la fonction par défaut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Bouteille : public Objet
    {
    public:
      Bouteille(int poid, int poidLiquide) : Objet(poid), poidLiquide(poidLiquide) {}
     
      int getPoidTotal() {
        return Objet::getPoidTotal();
      }
    private:
      int poidLiquide;
    };

  3. #3
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    FAQ - Qu'est-ce qu'une fonction virtuelle pure ?
    L'intérêt d'une fonction virtuelle pure est de forcer l'utilisateur de ta classe à redéfinir cette fonction. Si ça ne doit pas être une obligation, alors ça devrait être une fonction virtuelle classique.

    Sinon :
    * this-> sert à rien
    * utilise les listes d'initialisation dans le constructeur de Objet (FAQ - Mes constructeurs doivent-ils utiliser les listes d'initialisation ou l'affectation ?)
    * non respect du principe de Liskov (FAQ - Qu'est-ce que le LSP ?)
    * n'utilise pas de God object

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 124
    Par défaut
    Ok, j'avais lu dans un cours de l'université de provence, dans la section "Version "par défaut" d'une fonction virtuelle pure", que la redéfinition d'une fonction virtuelle pure n'est pas obligatoire. (Pourquoi les appelle-t-on fonctions et non méthodes virtuelles pures ?) :
    Citation Envoyé par cours de l'université de provence
    Dans ces conditions, la classe CForme reste abstraite (elle ne peut pas être instanciée directement), mais les classes qui en sont dérivées n'ont pas à redéfinir la fonction surface() si celle-ci ne les concerne pas : elle héritent par défaut de la "version par défaut" définie dans la classe de base.
    S'agit il d'une erreur ou d'une incompréhension de ma part ?

    Sinon :
    Citation Envoyé par gbdivers Voir le message
    * this-> sert à rien
    * utilise les listes d'initialisation dans le constructeur de Objet (FAQ - Mes constructeurs doivent-ils utiliser les listes d'initialisation ou l'affectation ?)
    * non respect du principe de Liskov (FAQ - Qu'est-ce que le LSP ?)
    * n'utilise pas de God object
    Il faut bien comprendre que ce code n'est qu'un exemple destiné à synthétiser mon problème. Ce n'est pas mon vrai code. Mais j'essaye d'apprendre de tes remarques.
    En fait, j'ai oublié d'écrire ce constructeur avec une liste d'initialisation. Pour le this->, je ne suis pas sur de comprendre. this-> ne sert à rien pour les appels de variables globales ou this-> ne sert à rien dans mon constructeur ?

    Citation Envoyé par gbdivers Voir le message
    * non respect du principe de Liskov (FAQ - Qu'est-ce que le LSP ?)
    Je ne vois pas pourquoi le principe de Liskov n'est pas respecté. Bien sur il faut partir du principe (que je croyais correct) que la classe fille hériterait de la définition par défaut de la fonction virtuelle pure.
    Peux tu m'en dire un peu plus s'il te plait ? J'aimerai comprendre mon erreur.

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par DavidleVrai Voir le message
    Ok, j'avais lu dans un cours de l'université de provence, dans la section "Version "par défaut" d'une fonction virtuelle pure", que la redéfinition d'une fonction virtuelle pure n'est pas obligatoire. (Pourquoi les appelle-t-on fonctions et non méthodes virtuelles pures ?) :
    Le mot "méthode" n'a pas de sens en C++. On parle de fonctions, qui peuvent être des fonctions libres ou des fonctions membre, ces dernières pouvant être virtuelles ou pas, et les virtuelles pouvant être pures ou pas.

    Certains utilisent le mot méthode pour dire "fonction membre", d'autres pour dire "fonctions membres virtuelles". Donc, dans le doute, il vaut mieux éviter ce vocabulaire un peu flou.

    Citation Envoyé par DavidleVrai Voir le message
    S'agit il d'une erreur ou d'une incompréhension de ma part ?
    Je pense qu'il s'agit d'une erreur du document. Le fait de donner une implémentation à une fonction virtuelle pure est possible, mais la fonction n'en reste pas moins virtuelle pure, et devant être surchargée dans toute classe dérivée dont on souhaite pouvoir créer des instances.

    L'implémentation ne sert alors qu'à une chose : On peut appeler explicitement cette implémentation. Comme te l'a montré Lintel-oo

    C'est généralement assez rare comme écriture.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    124
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 124
    Par défaut
    Ok ! Je comprend un peu mieux les messages d'erreurs de visual à propos des membres...

    Effectivement, il y a une erreur dans le cours car la redéfinition ou la surcharge est obligatoire malgré tout. Mais la version par défaut peut être utile pour ne pas avoir à réécrire ce code.

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

Discussions similaires

  1. [ATL] Accéder à un attribut d'une classe qui hérite d'une classe abstraite
    Par chekaoui dans le forum Eclipse Modeling
    Réponses: 0
    Dernier message: 22/07/2014, 14h32
  2. Utilisation d'une structure au lieu d'une classe
    Par LinuxUser dans le forum C++
    Réponses: 10
    Dernier message: 23/11/2012, 13h03
  3. Réponses: 5
    Dernier message: 29/12/2010, 15h13
  4. la classe Action est-elle une classe abstraite?
    Par mrjeronimo dans le forum Struts 1
    Réponses: 2
    Dernier message: 21/05/2008, 11h29
  5. Héritage d'une classe MFC et d'une classe non MFC
    Par Etienne Paquette dans le forum MFC
    Réponses: 7
    Dernier message: 04/12/2007, 20h19

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