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 :

Méthode d'une classe virtuelle pure appelant une méthode virtuelle pure => Warning.


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut Méthode d'une classe virtuelle pure appelant une méthode virtuelle pure => Warning.
    Bonjour,

    J'ai une classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class VirtualListener
        {
        public:
            void maFonction(void);
     
        protected :
                inline virtual void logStartServeur(void) = 0;
        };
     
    void VirtualListener::maFonction(void)
    {
             logStartServeur();
    }
    Mais le compilateur me met un joli warning :
    warning: inline function ‘virtual void LD::VirtualListener::logStartServeur()’ used but never defined
    Je ne comprend pas l'intérêt d'un tel warning.
    VirtualListener est virtuel pure, on ne peut pas créer d'instance même en la dérivant à moins de donner l'implémentation de la méthode logStartServeur.
    Comment pourrais-je supprimer ce warning ?

  2. #2
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par défaut
    Je ne comprend pas trop comment une méthode virtuelle pure peut être inline ? (c'est une vraie question)

    Pour une méthode virtuelle non pure, le corps peut être inliné si on appelle la méthode directement sur un objet (ni une référence ni un pointeur), mais dans tous les autre cas l'inline est impossible puisque la véritable fonction appelée est choisie au run time.

    Dans le cas d'une méthode virtuelle pure, il est impossible d'instancier un objet, et donc le seul cas d'application du caractère inline disparait.

    Qui plus est, il me semble que le mot clé inline ne fait pas vraiment partie du prototype de la méthode, dans le sens où :
    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
    class TestBase
    {
    public :
     
        virtual ~TestBase();
     
        inline virtual void foo() = 0;
    };
     
    class Test : public TestBase
    {
    public :
     
        void foo() override {}
    };
    ... compile parfaitement, alors que la méthode dérivée n'est elle même pas inline. En revanche, ce code produit le même warning que dans ton message précédent, warning qui disparait si on supprime le mot clé inline de la méthode de base.

  3. #3
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Le mot clé "inline" n'est qu'une indication qu'on donne au compilateur.

    Ici, j'ai une classe virtuelle dont hérite deux autres classes.

    Ces classes utilisent plusieurs méthodes ne variant souvent que d'une ligne.

    La solution la plus simple est de faire une méthode virtuelle pure (ou simplement virtuelle si on veut mettre une ligne par défaut) et de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    virtual void VirtualListener::maMéthode(void)
    {
             //début
             logStartServeur();
             //fin
    }
    Mais appeler une fonction reste une chose assez lourde pour finalement pas grand chose...
    Après, est-ce que le compilateur est suffisamment intelligent pour comprendre qu'il faut créer pour chaque classe fille une méthode maMéthode et mettre le contenu de logStartServeur dedans? Dans le doute...


    Une autre solution serait de définir tout ce qui est inline chez la mère et de définir une méthode virtuelle pure qu'on implémenterais chez la fille :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void Fille::maMethode()
    {
           debut();
           //....
           fin();
    }
    Mais ceci ne me semble pas super...


    EDIT : je n'avais pas vu que tu avais été pendant que j'écrivais.
    Comme la méthode inline virtuelle est appelée au sein d'une méthode qui est elle aussi virtuelle, le compilateur sait dès la compilation quelle méthode inline utiliser.
    Par contre est-il capable de faire l'optimisation ?

  4. #4
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Après, est-ce que le compilateur est suffisamment intelligent pour comprendre qu'il faut créer pour chaque classe fille une méthode maMéthode et mettre le contenu de logStartServeur dedans?
    J'en doute fortement. Mais pour être sûr, il faut regarder le code assembleur, et ça sort un peu de mes compétences

    Citation Envoyé par Neckara Voir le message
    Une autre solution serait de définir tout ce qui est inline chez la mère et de définir une méthode virtuelle pure qu'on implémenterais chez la fille :
    Ca me semble déjà plus probable. En soit, ce n'est pas nécessairement une mauvaise idée si tu peux vraiment ranger début et fin dans deux fonctions qui aient un sens.

    Edit : je n'avais pas vu que tu n'avais pas vu que j'avais écrit pendant que tu écrivais...
    Citation Envoyé par Neckara Voir le message
    Comme la méthode inline virtuelle est appelée au sein d'une méthode qui est elle aussi virtuelle, le compilateur sait dès la compilation quelle méthode inline utiliser.
    Dans ton code original, la seconde méthode n'est pas virtuelle. Ton but n'était justement pas d'éviter à ré-écrire maFonction dans toutes les classes dérivées ?

  5. #5
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par Kalith Voir le message
    Ca me semble déjà plus probable. En soit, ce n'est pas nécessairement une mauvaise idée si tu peux vraiment ranger début et fin dans deux fonctions qui aient un sens.
    C'est justement ça le problème il faut que ça ai un sens et ceci va me rajouter plus de méthodes inline à créer.
    J'ai peur que la classe devienne illisible avec trop de méthodes...

    EDIT : Ou alors une classe virtuelle pure pour l'interface.
    Et un ensemble de classes/namespace pour les méthodes/fonctions inlines ?
    Fin EDIT.

    Citation Envoyé par Kalith Voir le message
    Dans ton code original, la seconde méthode n'est pas virtuelle. Ton but n'était justement pas d'éviter à ré-écrire maFonction dans toutes les classes dérivées ?
    Heu... Si, je commence juste à m'embrouiller^^
    J'étais en train de me demander si appeler une méthode inline virtuelle dans un méthode virtuelle ne forcerait pas le compilateur à réécrire lui-même la méthode virtuelle pour chaque fille.
    Ce n'est pas totalement illogique et ça m'arrangerait bien

  6. #6
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Je viens juste d'y penser, les templates réécrivent la fonction ou la classe pour chaque type pouvant être utilisé non?

    Dans ce cas là est-ce qu'on ne pourrait pas faire :
    - Une classe virtuelle pure (A) servant d'interface.
    - Une classe templaté (B) héritant de la classe A qui implémentera toutes les méthodes.
    - Une classe virtuelle pure (C) avec des méthodes virtuelles pures inlines.
    - Des classes héritant de A (D) qui contiendra l'implémentation de ces méthodes inlines.

    Ce qui donnerais :
    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
     
    class D : A
    {
             static inline void fctInline(void);
    };
     
    <typename T>
    void B<>::Methode()
    {
             //debut
            T::fctInline();
            //fin
    }
     
     
    A * a = B<D>::newB();
     
    a->Methode();

    Qu'en pensez-vous?

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 02/07/2013, 09h04
  2. Réponses: 1
    Dernier message: 23/12/2011, 17h45
  3. appeler une classe au sein d'une servlet
    Par switch1 dans le forum Hibernate
    Réponses: 10
    Dernier message: 22/05/2009, 21h11
  4. Appeler une Applet ou servlet depuis une classe java
    Par oussam dans le forum Applets
    Réponses: 2
    Dernier message: 04/07/2006, 13h58
  5. Réponses: 14
    Dernier message: 15/12/2005, 18h46

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