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 :

Virtual, inline, explicit ?


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Avril 2008
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 187
    Points : 65
    Points
    65
    Par défaut Virtual, inline, explicit ?
    Bonjour tous le monde
    j'ai jamais travaillé avec le langage C++, et j'ai un parseur à faire, donc je dois comprendre bien la syntaxe de c++
    ma question est sur les methodes virtual, inline, et explicit
    je veux savoir leurs sens, à quoi servent-ils ? et si possible leurs equivalents par rapport aux modificateurs de java?

    Merci pour votre aide

  2. #2
    Membre averti Avatar de Dalini71
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    181
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 181
    Points : 343
    Points
    343
    Par défaut


  3. #3
    Membre du Club
    Inscrit en
    Avril 2008
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 187
    Points : 65
    Points
    65
    Par défaut
    Oh merci pour votre aide
    justement j'ai cherché sur Google, et j'ai lu la faq, mais j'ai pas bien compris (j'ai bien dit au début, j'ai jamais travaillé avec le C++)
    je veux plus d'explication

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    • virtual Signale au compilateur que le comportement de la fonction est susceptible d'être modifié dans un contexte d'héritage et de polymorphisme. Ce mot aura pour résultat de placer un pointeur vers la fonction en question dans une "vtable" et permettra d'en appeler la version correcte en fonction du type réel d'un objet qui se ferait passer pour un objet du type parent
    • inline demande au compilateur de remplacer tous les appels d'une fonction par le code qui la compose. Le but principal étant d'espérer gagner un peu de temps lors de l'appel: En effet, un appel classique de fonction "perd" un peu de temps à placer une série d'informations dans la pile d'appel avant d'en effectuer le contenu. Quand une fonction est inlinée, ces informations ne sont pas placées en pile d'appel.
    • explicit indique qu'un constructeur doit explicitement être appelé lorsque l'on veut l'utiliser. En effet, un constructeur prenant un argument unique peut servir d'opérateur de conversion implicite du type de l'argument vers le type de la classe dont on défini le constructeur. Comme un tel comportement peut poser problèmes dans certaines circonstances, le fait de déclarer le constructeur explicit empêche la conversion implicite
    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

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Au niveau des équivalences de java, je ne les connais pas trop, mais j'ai au moins retenu ça: En java, toutes les méthodes sont virtual par défaut, sauf (peut-être) quand on les déclare final.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    349
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 349
    Points : 379
    Points
    379
    Par défaut
    Je rajouterais même pour virtual

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    virtual void f(); //la fonction peut être redéfinie dans une une sous-class
    virtual void f() = 0;la fonction doit être redéfinie dans une une sous-class -> la class devient abstraite
    [troll]
    inline ne doit pas exister en Java qui n'est pas axé performances
    [/troll]

    Quand à explicit je dois avouer que je ne l'utilise jamais, mais finalement ce serait pas plus logique que tout soit explicit par défaut et d'avoir un mot clef implicite? Si quelqu'un peut m'éclairer plus sur l'utilisation d'explicit je suis preneur

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    virtual = 0, c'est (généralement) l'équivalent du abstract de java.

    Quant à explicit, je pense la même chose que toi. Quant à l'exemple: Beware the C++ implicit conversion
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Imagine une classe dont un des constructeurs possibles ne prenne qu'un unique argument.

    Par exemple, une classe proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class MaClass
    {
        public:
            MaClass(int ) ;
            /* tout le reste */
    };
    Ce constructeur sert implicitement d'opérateur de conversion entre un objet de type int (dans l'exemple, mais nous pourrions généraliser en disant "le type de l'argument") et un objet de type MaClass (autrement dit: de la classe dont fait partie le constructeur).

    Si, ailleurs, tu as une fonction penant comme argument un objet de type MaClass (qu'il soit passé par valeur ou par référence n'y change rien) donc dont le prototype pourrait ressembler à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void foo(MaClass /* const */ /* & */ );
    tu pourrais tout à fait appeler cette fonction en lui passant, simplement, un int (selon l'exemple):

    En effet, dans ce cas, le int passé en argument serait implicitement (c'est à dire en dehors de tout controle de l'auteur) transformé en un objet de type MaClass et c'est cet objet qui sera utilisé au sein de la fonction.

    Dans une bonne majorité des cas, cela ne posera pas problème.

    Mais, imaginons maintenant que ce constructeur alloue dynamiquement la mémoire pour N*N élément imposants (où N est la valeur de notre argument) puis qu'il suive une logique imposante pour remplir cet espace, voire, si notre argument est une std::string, tente d'ouvrir un fichier, de le lire, et d'en extraire une grosse partie pour construire notre objet de type MaClass.

    Tu voudrais surement éviter cette étape de construction imposante, surtout si... tu dispose d'une instance de la classe en question construite selon ces critères.

    Or, l'idée est de se dire que le compilateur est ton ami, et que ton pire ennemi, c'est... toi-même (et surtout ta distraction).

    En déclarant le constructeur explicite, tu ne pourra plus écrire un code qui compile (et qui fonctionne, en plus, correctement) sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main()
    {
        foo(10000);
        return 0;
    }
    parce que le compilateur se plaindra alors qu'il n'existe aucun moyen de conversion implicite.

    Par contre, si ton idée est effectivement de créer un objet "à la volée", tu peux malgré tout le faire, en adoptant un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main()
    {
        foo(MaClass(10000));
        return 0;
    }
    Mais, au moins, tu demande explictement la création de l'objet.
    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

  9. #9
    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
    Après, il y a encore quelques subtilités :
    inline : le compilateur peut très bien ne pas inliner la fonction. In fine, l'inlining est toujours à la discrétion du compilateur modulo les options qui lui sont passés.
    inline : permet aussi plusieurs définition d'un symbole dans différentes translation unit (disons .obj) :
    Globale.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    inline void f()
    {
    }
    void g()
    {
    }
    Si Globale est inclue dans A.cpp, B.cpp et C.cpp, alors une seule version de f() est générée alors que 3 versions de g (ce qui provoquera un problème de lien il me semble). Voir cette discussion et celle-ci.

    virtual : dans un contexte non polymorphe certains compilateurs n'utilisent pas la vtable pour l'appel des fonctions virtuelles qui se comportent alors comme des fonctions 'normales' :
    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
    struct A
    {
       virtual void f(){}
       void g(){}
    };
     
    struct B : public A
    {
       virtual void f(){}
    };
     
     
    int main()
    {
       A a;
       a.f();
       a.g();
     
       B b;
       b.f();
       b.g();
     
       A&ra(b);
       ra.f();
       ra.g();
     
       return 0;
    }
    Donne avec Visual Express :
    Code asm : 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
    39
    40
    41
    ;int main()
    ;{
    push        ebp  
    mov         ebp,esp 
    sub         esp,0Ch 
    ;   A a;
    lea         ecx,[a] 
    call        A::A (40100Fh) 
    ;   a.f();
    lea         ecx,[a] 
    call        A::f (40101Eh) 
    ;   a.g();
    lea         ecx,[a] 
    call        A::g (401014h) 
     
    ;   B b;
    lea         ecx,[b] 
    call        B::B (40100Ah) 
    ;   b.f();
    lea         ecx,[b] 
    call        B::f (401005h) 
    ;   b.g();
    lea         ecx,[b] 
    call        A::g (401014h) 
     
    ;   A&ra(b);
    lea         eax,[b] 
    mov         dword ptr [ra],eax 
    ;   ra.f();
    mov         ecx,dword ptr [ra] 
    mov         edx,dword ptr [ecx] 
    mov         ecx,dword ptr [ra] 
    mov         eax,dword ptr [edx] 
    call        eax  
    ;   ra.g();
    mov         ecx,dword ptr [ra] 
    call        A::g (401014h) 
     
    ;   return 0;
    xor         eax,eax 
    ;}
    Si je comprend bien seul l'appel à ra.f() passe par la vtable.

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Sur le coup, j'ai eu du mal à comprendre comment il appelait, car je m'emmêlais dans les déréférencements:
    Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    mov         ecx,dword ptr [ra] ;charge la référence (ici, pointeur déguisé) dans ECX
    mov         edx,dword ptr [ecx] ;pointeur de vtable dans EDX
    mov         ecx,dword ptr [ra] ;re-charge la référence dans ECX pour appel en __thiscall (le code n est pas optimisé).
    mov         eax,dword ptr [edx] ;premier pointeur de fonction de la vtable
    call        eax
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    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 Médinoc Voir le message
    re-charge la référence dans ECX pour appel en __thiscall (le code n est pas optimisé).
    J'ai laissé le mode debug sans optimisation, car en release (/Ox /GL) sur un code aussi simple, il reste ça
    Code ASM : 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
    ;int main()
    ;{
    push        ecx  
    ;   A a;
    ;   a.f();
    ;   a.g();
     
    ;   B b;
    ;   b.f();
    ;   b.g();
     
    ;   A&ra(b);
    ;   ra.f();
    lea         ecx,[esp] 
    mov         dword ptr [esp],offset B::`vftable' (402100h) 
    call        dword ptr [B::`vftable' (402100h)] 
    ;   ra.g();
     
    ;   return 0;
    xor         eax,eax 
    ;}
    D'ailleurs c'est intéressant de voir qu'il a giclé tous les autres appels (les fonctions sont vides donc l'inline n'a généré aucun code) mais doit encore faire l'appel à f dans un cadre polymorphe car il ne sait pas quelle version est appelée.

  12. #12
    Membre du Club
    Inscrit en
    Avril 2008
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 187
    Points : 65
    Points
    65
    Par défaut
    Merci pour vos réponses
    comme je prépare une grammaire Syntaxique de C++, j'aurais besoin des documents qui explique bien la syntaxe du langage,
    pouvez-vous m'aider sur ça ?

    Merci encore une fois

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    J'espère que par "grammaire syntaxique" tu ne parles pas au sens mathématiques et théorie des langages, car la syntaxe C++ est assez horrible à analyser, si je me souviens bien.
    Déjà le C ne peut pas être une grammaire pure à cause des typedefs (qui t'obligent à coller une table de symboles dans l'analyseur lexical), mais il me semble qu'en C++ c'est pire.

    Mais C++/CLI est sans doute encore pire, vu tous les nouveaux mots-clés qui dépendent du contexte (ref, each, value, abstract, sealed...)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    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,
    Il me semble que la 'grammaire' est définie dans la norme à la fin en annexe. Cette dernière est payante.
    Sur le MSDN il y a la grammaire pour le C mais je n'ai pas vu celle pour le C++.

  15. #15
    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
    On peut trouver des résumé de la grammaire C++, comme ici
    "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)

  16. #16
    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
    Tu peux regarder SCALPEL qui un analyseur syntaxique / sémantique C++, produit par un des membres :

    http://42ndart.org/scalpel/
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  17. #17
    Membre du Club
    Inscrit en
    Avril 2008
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 187
    Points : 65
    Points
    65
    Par défaut
    Merci Davidbrcz je trouve ce lien vraiment intéressant

    Merci pour votre aide
    Merci pour tous

Discussions similaires

  1. Réponses: 3
    Dernier message: 04/05/2010, 13h18
  2. inline et virtual
    Par casafa dans le forum C++
    Réponses: 6
    Dernier message: 01/09/2006, 12h49
  3. Virtual-key code
    Par lyrau dans le forum Windows
    Réponses: 2
    Dernier message: 29/03/2003, 19h22
  4. [Turbo C++] Fonciton containing for are not expanded inline
    Par BuG dans le forum Autres éditeurs
    Réponses: 6
    Dernier message: 17/02/2003, 06h48
  5. Abstract VS virtual
    Par LE CHAKAL dans le forum Langage
    Réponses: 2
    Dernier message: 29/08/2002, 17h50

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