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 pure et implémentation par défaut.


Sujet :

Langage C++

  1. #1
    Invité
    Invité(e)
    Par défaut méthode virtuelle pure et implémentation par défaut.
    Salut,
    Problèmes du jour:
    J'ai une classe abstraite que voilà
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
    class A
    {
    	public:
    		virtual void exec()=0 {return;}
    };
    apparament le compilateur ne semble pas apprécier que je définisse la méthode exec dans la déclaration de la classe.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    13 C:\Documents and Settings\Utilisateur\Bureau\test2.cpp pure-specifier on function-definition
    Dans mon cours de langage, la définition pouvait se faire à l'intérieur de la classe. Cela atil changé??

    Qu'à cela ne tienne, tentons de la définir en dehors.
    J'ai mainetenant un système de classes que voila:

    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 A
    {
    	public:
    		virtual void exec()=0;
    };
     
    void A::exec()
    {
    	return;
    }
     
     
     
     
     
    class B
    {
    	public:
    		void exec(){cout << "blabla" << endl;}
    };
     
     
    class C: public A, public B
    {
    	public :
    		using B::exec;
    };
     
     
    int main()
    {
    	C c;
    	c.exec();
    }
    Ici, le compilo cale à la déclaration de "c" dans le main. car soidisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    43 C:\Documents and Settings\Utilisateur\Bureau\test2.cpp cannot declare variable `c' to be of type `C' 
    43 C:\Documents and Settings\Utilisateur\Bureau\test2.cpp   because the following virtual functions are abstract: 
    17 C:\Documents and Settings\Utilisateur\Bureau\test2.cpp  virtual void A::exec()
    Je pensais qu'on pouvait définir un comportement par défaut aux méthodes virtuelles pures que s'il n'est pas redéfini par une classe fille, ce sera le comportement adopté par cette dernière.

    Ou bien ça a changé??
    Ou bien jai foiré quelque part dans mon code??

  2. #2
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Bonjour,
    Citation Envoyé par thenano
    Je pensais qu'on pouvait définir un comportement par défaut aux méthodes virtuelles pures que s'il n'est pas redéfini par une classe fille, ce sera le comportement adopté par cette dernière.
    Edit : Oups, je m'ai trompé.
    Effectivement d'après la faq c'est possible...
    Qu'est-ce qu'une fonction virtuelle pure ?
    Qu'est-ce qu'une classe abstraite ?

  3. #3
    Membre régulier
    Profil pro
    System Integration Project Manager
    Inscrit en
    Octobre 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : System Integration Project Manager
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 219
    Points : 112
    Points
    112
    Par défaut
    Salut,
    Citation Envoyé par thenano Voir le message
    Je pensais qu'on pouvait définir un comportement par défaut aux méthodes virtuelles pures que s'il n'est pas redéfini par une classe fille, ce sera le comportement adopté par cette dernière.

    Ou bien ça a changé??
    Ou bien jai foiré quelque part dans mon code??
    t'as loupé un chapitre peut etre

    Une methode virtuelle pure n'a pas de comportement par defaut. C'est aux classes derivees de le definir car sinon tu ne pourras meme pas instancier un objet de cette classe.

    Si tu veux avoir une methode avec un comportement par defaut, alors il te faut coder ce comportement et utiliser le mot clé virtual comme tu l'as fait mais il faut virer le =0.

    V

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    865
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 865
    Points : 1 069
    Points
    1 069
    Par défaut
    Citation Envoyé par thenano
    Dans mon cours de langage, la définition pouvait se faire à l'intérieur de la classe. Cela atil changé??
    La norme dit le contraire.
    a function declaration cannot provide both a pure-specifier and a definition
    Est-ce que ton cours précise quel compilo est utilisé ? C'est peut-être une liberté donnée par un compilo mais ce comportement ne respecte pas la norme.

    Citation Envoyé par vdaanen
    Une methode virtuelle pure n'a pas de comportement par defaut.
    Si, justement c'est possible. Voir la FAQ http://cpp.developpez.com/faq/cpp/?p...ction_vituelle

  5. #5
    Membre régulier
    Profil pro
    System Integration Project Manager
    Inscrit en
    Octobre 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : System Integration Project Manager
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 219
    Points : 112
    Points
    112
    Par défaut
    Citation Envoyé par aoyou Voir le message
    Si, justement c'est possible. Voir la FAQ http://cpp.developpez.com/faq/cpp/?p...ction_vituelle
    mea culpa !
    mais je ne vois pas l'intérêt d'avoir un comportement pas défaut sur une méthode virtuelle pure puisque cette dernière doit être reimplementée...
    c'est pas clair je trouve cette histoire...

  6. #6
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
     
    class C: public A, public B
    {
    	public :
    		void exec() { B::exec(); }
    };
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  7. #7
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    cannot declare variable `c' to be of type `C'
    because the following virtual functions are abstract:
    virtual void A::exec()
    En fait, ce problème n'est pas lié à la définition par défaut de exec dans A. Il manque une fonction virtuelle exec dans la classe C qui redéfinirait la fonction virtuelle exec de A. C possède certes une fonction exec() hérité de B, mais C ne remplit quand même pas son contrat avec A.

    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
     
    class A
    {
       public:
          virtual void exec()=0;
    };
     
    void A::exec()
    {
       return;
    }
     
    class B
    {
       public:
          void exec(){std::cout << "exec B" << std::endl;}
    };
     
     
    class C: public A, public B
    {
       public :
          virtual void exec();
             using B::exec;
    };
     
    void C::exec()
    {
        std::cout << "exec A" << std::endl;
    }
     
     
    int main()
    {
        C c;
        c.exec(); // affiche exec A
        c.B::exec(); // affiche exec B
    }

  8. #8
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Citation Envoyé par Goten Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class C: public A, public B
    {
    	public :
    		void exec() { B::exec(); }
    };
    Boudiou, ça marche en effet !
    Goten, explique !

  9. #9
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Qu'est ce qui te paraît pas clair dans le fait que ça marche? Car bizarrement moi ça me parle, je trouve ça naturel... (peut être signe d'incompréhension partielle d'ailleurs).
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  10. #10
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    En fait, j'étais totalement persuadé que :
    1) Une fonction virtuelle pure ne pouvait pas avoir d'implémentation par défaut.
    2) Il fallait remettre le mot clé virtual dans la classe fille pour redéfinir la fonction virtuelle pure de la classe abstraite.

    Faux sur toute la ligne...
    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
     
    #include <iostream>
    struct A
    {
       public:
       virtual void exec() = 0
       {
          std::cout << "A" << std::endl;
       };
    };
     
    class C: public A
    {
       public :
       /* virtual */ void exec(){ std::cout << "exec C" << std::endl; }
    };
     
    int main()
    {
        A* a = new C;
        a->exec(); // affiche "exec C"
    }

  11. #11
    Invité
    Invité(e)
    Par défaut
    Merci pour toutes vos réactions
    Citation Envoyé par Goten Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class C: public A, public B
    {
    	public :
    		void exec() { B::exec(); }
    };
    En effet cette solution fonctionne, et c'est normal.

    Ce que je n'avais pas compris c'est que le fait de proposer une implémentation par défaut pour une méthode virtuelle pure ne dispense pas la classe fille de redéfinir cette méthode en appelant l'implémentation par défaut de la classe abstraite.

    Dans mon cas cela ne sert à rien, puisque je veux appeler la méthode exec de B et pas de A. (et je voulais faire ça par un using, et non pas en utilisant la solution de Goten) // juste pour voir si c'était faisable.
    Pour cela oui, il faudrait rendre A::exec virtuelle "impure" càd sans =0.

    jai tout compris
    Merci

  12. #12
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Citation Envoyé par vdaanen Voir le message
    mea culpa !
    mais je ne vois pas l'intérêt d'avoir un comportement pas défaut sur une méthode virtuelle pure puisque cette dernière doit être reimplementée...
    c'est pas clair je trouve cette histoire...
    L'intérêt, c'est que tu peux tout à fait donner comme comportement par défaut qu'il te suffira d'invoquer explicitement sans devoir le copier dans toutes les classes filles qui s'en contentent.

    Plutôt que d'avoir un code proche de
    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
    class Mere
    {
        public:
            virtual void foo() =0; // non implémenté, donc à réimplémenter dans
                                         // toutes les classes dérivées
    };
    class Fille1: public Mere
    {
        public:
            virtual void foo();
    };
    class Fille2: public Mere
    {
        public:
            virtual void foo();
    };
    void Fille1::foo()
    {
        /* une logique potentiellement imposante qui pourrait servir de
         *  comportement par défaut
         * et s'étendant éventuellement sur de nombreuses instructions / 
         * tests / boucles
         */
    }
    void Fille2::foo()
    {
        /* exactement le même comportement que dans Fille1
         * (ce qui entraine une duplication du code, qui n'est jamais souhaitable)
         */
    }
    tu aurais un code proche de
    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
    class Mere
    {
        public:
            virtual void foo() =0; 
    };
    class Fille1: public Mere
    {
        public:
            virtual void foo();
    };
    class Fille2: public Mere
    {
        public:
            virtual void foo();
    };
    void Mere::foo()
    {
        /* une logique potentiellement imposante qui sert de
         *  comportement par défaut
         * et s'étendant éventuellement sur de nombreuses instructions / 
         * tests / boucles
         */
    }
    void Fille1::foo()
    {
        /* Fille1 se contente du comportement par défaut */
        Mere::foo();
    }
    void Fille2::foo()
    {
        /* et Fille2 aussi */
        Mere::foo();
    }
    Le fait qu'une duplication de code n'est jamais souhaitable se rapporte aux deux axiomes suivants:
    • Axiome : Plus le nombre de lignes de codes est élevé, plus il y aura de bugs dedans, et plus la probabilité d'en oublier un est élevée.
    • Axiome : Tout code inutile (code mort et/ou redondant, ce qui n'inclus pas le code de conservation d'intégrité bien sûr) est une source de bugs et/ou de perte de performances, et doit donc être supprimé.
    (citation tronquée d'une intervention de Mac LAK d'aujourd'hui )

    et t'assure que, si un jour, tu en viens à vouloir modifier le comportement par défaut (ne serait-ce que parce que tu t'es rendu compte à l'usage que le comportement par défaut existant représente en réalité une exception), tu n'aura qu'à le modifier à un seul et unique endroit pour observer que toutes les classes dérivées qui utilisent ce comportement par défaut suivent le mouvement
    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

  13. #13
    Membre régulier
    Profil pro
    System Integration Project Manager
    Inscrit en
    Octobre 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : System Integration Project Manager
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 219
    Points : 112
    Points
    112
    Par défaut
    merci de tes explications .. je n'avais jamais vu la chose sous cet angle ...
    V

  14. #14
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Citation Envoyé par vdaanen Voir le message
    merci de tes explications .. je n'avais jamais vu la chose sous cet angle ...
    V
    Cela n'a pas grand chose de surprenant lorsque l'on débute en programmation...

    Ce n'est souvent que par expérience personnelle que l'on se rend compte des problèmes engendrés par la duplication de code (qui est souvent effectuée par un copier / coller ... sans prendre en compte qu'un argument a changé de nom au passage )

    C'est d'ailleurs le propre de tous les axiomes qui ne seraient pas explicitement exposés

    Et, quelque part, le but du forum est, justement, de permettre au gens d'avoir un angle de vue différent
    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

  15. #15
    Membre régulier
    Profil pro
    System Integration Project Manager
    Inscrit en
    Octobre 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : System Integration Project Manager
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 219
    Points : 112
    Points
    112
    Par défaut
    je ne suis pas vraiment un debutant mais j'ai plus appris le C++ par moi meme qu'en lisant les normes et autres Stroustrup...

    Ca fait 2/3 ans que je me documente reellement sur ce langage que j'utilise depuis pres de 10 ans ... mieux vaut tard que jamais comme on dit....

    V

  16. #16
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Citation Envoyé par vdaanen Voir le message
    je ne suis pas vraiment un debutant mais j'ai plus appris le C++ par moi meme qu'en lisant les normes et autres Stroustrup...

    Ca fait 2/3 ans que je me documente reellement sur ce langage que j'utilise depuis pres de 10 ans ... mieux vaut tard que jamais comme on dit....

    V
    Excuses moi, je ne voulais pas te vexer

    Quoi qu'il en soit, il est souvent intéressant de changer de point de vue
    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

  17. #17
    Membre régulier
    Profil pro
    System Integration Project Manager
    Inscrit en
    Octobre 2006
    Messages
    219
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : System Integration Project Manager
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 219
    Points : 112
    Points
    112
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Excuses moi, je ne voulais pas te vexer
    ouhla, ne t'inquiete pas, il en faut plus pour me vexer !
    Pour tout avouer, je pensais avoir une certaine maitrise du C++ en sortant des mes années universitaires (M2R+these+5 ans de labo) ...
    Avec le recul je m'apercois que j'avais une bonne pratique du langage mais que de nombreux outils/concepts m'etaient passé laaaaargement au dessus et depuis presque 3 ans, je re-apprend ce langage .....

    Citation Envoyé par koala01 Voir le message
    Quoi qu'il en soit, il est souvent intéressant de changer de point de vue
    OK a 200% avec toi

    V

  18. #18
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Je viens de me rappeler que j'avais ouvert une discussion similaire il y a quelques temps la dessus : [POO] Implémentation de fonction virtuelle pure dans la classe de base

    Peut être une nouvelle entrée pour la FAQ ?
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

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

Discussions similaires

  1. Réponses: 13
    Dernier message: 10/01/2013, 16h19
  2. Réponses: 5
    Dernier message: 14/10/2012, 20h25
  3. Réponses: 1
    Dernier message: 02/03/2007, 11h37
  4. Problème avec une méthode virtuelle pure
    Par Burckel dans le forum C++
    Réponses: 4
    Dernier message: 05/12/2006, 14h00
  5. implémentation par défaut
    Par BigNic dans le forum C++
    Réponses: 2
    Dernier message: 22/03/2006, 10h21

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