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

C++ Discussion :

Fonction appelant une fonction virtuelle pure


Sujet :

C++

  1. #1
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut Fonction appelant une fonction virtuelle pure
    Bonjour,

    Soit la classe suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class A
    {
        ....
        virtual void f();
        virtual void g() = 0;
        ....
    };
    Etant entendu que A n'est pas instanciable, est-il possible d'avoir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void A::f()
    {
        ....
        g();
        ....
    }
    La fonction f étant appelée par les classes dérivées de A, qui elles ont implémenté g.

    Merci.

  2. #2
    Membre averti

    Inscrit en
    Juillet 2008
    Messages
    186
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 186
    Points : 350
    Points
    350
    Par défaut
    Oui

  3. #3
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 73
    Points : 68
    Points
    68
    Par défaut
    C'est tout à fait possible. Cela permet par exemple de définir un algorithme général dont certaines étapes sont définies par les classes dérivées (google Template Method Pattern).

  4. #4
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    +1.
    Exact c'est la base du Template Method...
    Le seul problème qu'il peut y avoir, c'est que tu ne peux pas appeler de fonctions virtuelles PURES dans ton constructeur. Sur une fonction membre comme dans ton exemple c'est OK...

    EDIT : ajout du mot PURE

  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
    Citation Envoyé par poukill Voir le message
    Le seul problème qu'il peut y avoir, c'est que tu ne peux pas appeler de fonctions virtuelles dans ton constructeur.
    Pour la même raison, vaut mieux éviter aussi dans le destructeur.
    P.S.: j'ai juste une question. Quand on se pose un pb comme celui là, le meilleur moyen de le résoudre n'est-il pas encore de faire une petite appli pour vérifier le comportement du compilo et l'exécution?
    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
     
    #include <iostream>
    class A{
    public:
     virtual void f()
       {
          g();
       }
       virtual void g()=0;
    };
    class B: public A
    {
    public:
      void g(){std::cout<<"B::g";}
    };
    int main()
    {
     B b;
     b.f();
    }
    Ca prend 3 minutes et on a la réponse.

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Merci à tous, notamment de m'avoir informé de l'existence du patron template method. Je suis à présent le nez dans le bouquin des GOF pour approndir la chose.

    Faudrait que je le lise une bonne fois pour toute, mais je lis déjà le Stroustrup chez moi et les Scott Meyers dans le métro (ça rentre par un oeil et ça sort par l'autre...).

    PS à 3DArchi : Tu as raison. J'ai péché par flemme et je m'en excuse.

  7. #7
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    P.S.: j'ai juste une question. Quand on se pose un pb comme celui là, le meilleur moyen de le résoudre n'est-il pas encore de faire une petite appli pour vérifier le comportement du compilo et l'exécution?
    Ca prend 3 minutes et on a la réponse.
    Oui, sauf que des fois c'est bien de comprendre pourquoi. Et étant donné le large panel de compilateur qui donne des choses parfois très différentes à la compilation !!

  8. #8
    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
    Citation Envoyé par poukill Voir le message
    Oui, sauf que des fois c'est bien de comprendre pourquoi. Et étant donné le large panel de compilateur qui donne des choses parfois très différentes à la compilation !!
    Sur le principe d'accord, mais pour une question aussi simple, j'ai des doutes. Et puis, à ce moment, la question serait 'pourquoi ça marche?' et non 'est-ce que ça marche?'

  9. #9
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    C'est pas faux... Mais quand ça marche, commet savoir que ça ne devrait pas marcher ?

  10. #10
    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
    Citation Envoyé par poukill Voir le message
    C'est pas faux... Mais quand ça marche, commet savoir que ça ne devrait pas marcher ?
    En évitant la pensée magique. Soit tu sais pourquoi ça marche (même si ton raisonnement peut être faux), et tu ne te poses plus de questions, soit tu ne comprend pas pourquoi ça marche, et là c'est intéressant de savoir.

  11. #11
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Citation Envoyé par poukill Voir le message
    +1.
    Exact c'est la base du Template Method...
    Le seul problème qu'il peut y avoir, c'est que tu ne peux pas appeler de fonctions virtuelles dans ton constructeur. Sur une fonction membre comme dans ton exemple c'est OK...
    C'est moyennenmant vrai.
    Il est possible d'appeler des fonctions virtuelles dans le constructeur (ou dans le destructeur), mais c'est la résolution statique des liens qui aura lieu ( comprendre que le polymorphisme ne marchera pas).

    Par contre, il est formellement interdit d'appeler une fonction virtuelle pure dans le constructeur (ou dans le destructeur). De mémoire, g+= refuse de compiler un tel code et ca ne me choquerai pas que cela soit un UB.

    Edit: j'ai retrouvé la justification:
    Citation : Norme C++ (10.4)
    Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  12. #12
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    C'est moyennenmant vrai.
    Il est possible d'appeler des fonctions virtuelles dans le constructeur (ou dans le destructeur), mais c'est la résolution statique des liens qui aura lieu ( comprendre que le polymorphisme ne marchera pas).
    En fait... pas vraiment... exemple:
    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
     
    class A
    {
        void doIt();
        virtual void f() = 0;
    };
     
    class B
    {
        B();
        virtual void f();
    };
     
    void A::doIt()
    {
        f();
    }
     
    B::B()
    {
        doIt();   // <= va bien appeler B::f();
    }
    En fait... pendant le contructeur de B (ou son destructeur), l'objet est de type "B" (même si c'est un C qui est créé).


    Par contre, il est formellement interdit d'appeler une fonction virtuelle pure dans le constructeur (ou dans le destructeur). De mémoire, g+= refuse de compiler un tel code et ca ne me choquerai pas que cela soit un UB.
    La encore... ca dépend...
    La fonction virtuelle pure peut très bien avoir une implémentation !
    Le "= 0" signifiant "doit être overridé".
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  13. #13
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par Davidbrcz
    C'est moyennenmant vrai.
    Il est possible d'appeler des fonctions virtuelles dans le constructeur (ou dans le destructeur), mais c'est la résolution statique des liens qui aura lieu ( comprendre que le polymorphisme ne marchera pas).
    +1.
    OUUlà mince. Au temps pour moi.
    Effectivement, je me souviens qu'on peut appeler une méthode virtuelle dans un constructeur... Par contre, je me souviens aussi que ce n'étais pas conseillé... Je viens de vérifier dans Standard de programmation en C++ (Sutter et Alexandrescu) )

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

Discussions similaires

  1. Appel d'une fonction dans une fonction d'une même classe
    Par script73 dans le forum Général Python
    Réponses: 3
    Dernier message: 06/03/2015, 10h18
  2. Faire appel à une fonction dans une fonction
    Par ThonySp dans le forum Scilab
    Réponses: 4
    Dernier message: 03/03/2015, 11h35
  3. Appeler une fonction dans une fonction
    Par bryanstaubin dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 18/06/2007, 09h39
  4. [Javascript] Appeler une fonction d'une fenêtre parente
    Par TekP@f dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 26/08/2005, 11h33
  5. [DLL] problème pour appeler une fonction d'une DLL
    Par bigboomshakala dans le forum MFC
    Réponses: 34
    Dernier message: 19/07/2004, 11h30

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