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 :

Comment l'appel à une méthode virtuelle....


Sujet :

C++

  1. #1
    Membre à l'essai
    Inscrit en
    Juillet 2004
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 19
    Points : 12
    Points
    12
    Par défaut Comment l'appel à une méthode virtuelle....
    est il implemente par un compilateur C++?
    s'il vous plait aidez moi a repondre a cette question , c'est pour un exam!

    merci..

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    En gros, toute classe possédant au moins une méthode virtuelle va se voir attribuer par le compilateur une table virtuelle (v-table), contenant des pointeurs vers les méthodes virtuelles. Tu pourras trouver plus de doc sur le net a propos des v-tables ...Surtout si c'est pour un exam

  3. #3
    Membre éprouvé Avatar de Caine
    Inscrit en
    Mai 2004
    Messages
    1 028
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 028
    Points : 1 122
    Points
    1 122
    Par défaut
    Bonjour,
    Lorsque tu déclares au moins une fonction virtuelle quelquepart dans la hiérarcie d'un objet, il y a création d'une table virtuelle de méthode (aussi nommée VMT).

    Quand tu demandes à exécuter la-dite méthode virtuelle : Recherche si l'objet à sa propre VMT, si oui, la fonction demandée y est-elle?
    Si elle y est, elle s'exécute, sinon on lance la recherche sur la VMT du parent, ainsi de suite jusqu'à trouver la méthode.

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Si elle y est, elle s'exécute, sinon on lance la recherche sur la VMT du parent, ainsi de suite jusqu'à trouver la méthode.
    A vérifier, mais je crois que la table de tous les objets sera complète, si une méthode n'a pas été surdéfinie l'entrée correspondante pointera simplement sur la méthode de la classe mère. Il n'y a pas de recherche récursive comme tu le suggères.

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2002
    Messages : 290
    Points : 325
    Points
    325
    Par défaut
    Citation Envoyé par Loulou24
    Si elle y est, elle s'exécute, sinon on lance la recherche sur la VMT du parent, ainsi de suite jusqu'à trouver la méthode.
    A vérifier, mais je crois que la table de tous les objets sera complète, si une méthode n'a pas été surdéfinie l'entrée correspondante pointera simplement sur la méthode de la classe mère. Il n'y a pas de recherche récursive comme tu le suggères.
    La methode générale de la v-Table n'est effectivement pas recursive, le constructeur de chaque objet ecrit l'adresse des méthodes redefinies, si bien qu'a la fin la vtable est la liste des methodes virtuelles...

    Toutefois chaque compilo est libre de son implementation et il me semble que g++ n'utilise pas de v-table mais un autre mécanisme (à vérifier)

  6. #6
    Membre éprouvé Avatar de Caine
    Inscrit en
    Mai 2004
    Messages
    1 028
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 028
    Points : 1 122
    Points
    1 122
    Par défaut
    Je m'excuse si j'ai mal aiguillé cette personne,
    je me rapellé d'un cours ou la VMT et le mécanisme de recherche a été décrit comme ça.

    J'avoue que je n'ai pas vérifier dans les sources de g++, ni des autres compilateurs

    Quelqu'un connait-il un site sur le sujet ? ça peut être intéressant, car la méthode implémentée influence grandement les performance à l'exécution.

  7. #7
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Pour ce qui est des performances à l'exécution de manière générale, il y a le document n1359. (que je n'arrive pas à charger. C'est bizarre)

    Pour ce qui est des vtables (pas VMT en C++ -- même combat que pas de méthodes, mais des fonctions membre) il me semble aussi que les détails d'implémentation sont laissés à la discrétion des fournisseurs de compilos. Je me souviens d'un bouquin de Stanley Lipmann au sujet du "modèle Objet" du C++ (ou un titre comme ça) qui traitait justement des vtables.
    Pour ce qui est de la récurisivité des tables (comprendre cout non constant pour retrouver la bonne function)... je n'y crois pas beaucoup. Je n'en vois pas l'intérêt non plus.

    Parfois les ressources qui traitent de l'héritage multiple et sa variante en diamant abordent le sujet des vtables pour expliquer comment s'est mis en oeuvre.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  8. #8
    Membre habitué
    Profil pro
    Enculeur de mouches
    Inscrit en
    Septembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : Enculeur de mouches

    Informations forums :
    Inscription : Septembre 2003
    Messages : 133
    Points : 161
    Points
    161
    Par défaut
    En l'occurence je crois pouvoir vous aider (en ce qui concerne g++ en tout cas).
    D'une, OUI, il utilise une VTable (suffisemment d'erreurs liés à ça en utilisant Qt pour m'en convaincre...) Un petit test idiot qui marche : définissez une classe avec un destructeur virtuel, sans l'implémenter...
    Ex :
    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
     
    #include <iostream>
     
    using namespace std;
     
    class Foo {
     public :
      Foo(int barVal);
      virtual ~Foo();
     
      int bar();
     
     private :
      int _bar;
    };
     
    Foo::Foo(int barVal) : _bar(barVal) {}
     
    //Foo::~Foo() {}
     
    int Foo::bar() {return _bar;}
    ceci génère à l'édition de lien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    gimli test 57 % gcc -o foobar testcon1.cpp
    /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.1/../../../crt1.o(.text+0x18): In function `_start':
    ../sysdeps/i386/elf/start.S:98: undefined reference to `main'
    /users/dea/cahier/tmp/ccW19gwI.o(.text+0x8): In function `Foo::Foo[not-in-charge](int)':
    : undefined reference to `vtable for Foo'
    /users/dea/cahier/tmp/ccW19gwI.o(.text+0x20): In function `Foo::Foo[in-charge](int)':
    : undefined reference to `vtable for Foo'
    /users/dea/cahier/tmp/ccW19gwI.o(.text+0x5a): In function `__static_initialization_and_destruction_0(int, int)':
    : undefined reference to `std::ios_base::Init::Init[in-charge]()'
    /users/dea/cahier/tmp/ccW19gwI.o(.text+0x89): In function `__tcf_0':
    : undefined reference to `std::ios_base::Init::~Init [in-charge]()'
    /users/dea/cahier/tmp/ccW19gwI.o(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
    collect2: ld returned 1 exit status
    Voilà donc qui résoud le Pb de savoir s'il utilise une Vtable ou non...

    Pour ce qui est du fonctionnement de cette dernière, il me semble en effet que toutes les adresses de toutes les fonctions héritées sont présentent. En effet le fonctionnement est le suivant (je le sais pour avoir compilé en assembleur certain code pour comprendre le fonctionnement de fonction dites "virtual inline"... Sisi c'est possible, et en plus ça marche, à condition d'utiliser -O2, je crois...)
    En fait lors d'un appel de fonction, c'est l'instruction assembleur :qui est utilisé (hors fonctions/méthodes inline pour lesquelles l'appel est remplacé par le corps de la méthode). Lors d'un appel de fonctions/méthodes classique, "adresse" est une valeur fixée "en dur" (une constante, quoi).

    L'appel à une méthode virtuelle est plus proche de... Immaginons une bête structure C dotée de pointeurs de fonction. Et bien voilà !!!
    Le "call" ne prend pas en paramètre une valeur constante, mais une référence au pointeur, qui lui même contient l'adresse... Ainsi la même opération sur des instances différentes de la structure C peut aboutir au lancement de routines différentes...
    On peut écrire ceci en assembleur comme suit : adresse n'est plus l'adresse de la routine mais l'adresse du pointeur qui contient l'adresse de la routine.

    Dans le cas des méthodes virtuelles (en tout cas sous G++, mais je suspecte que ce fonctionnement n'est pas différent avec d'autres compilos), adresse vaut en fait :
    adresse = adresseObj + OFFSET
    OFFSET est une constante, qui dépend de la méthode appellée (calculé à la compil'). Puisque la VTable appartient à l'objet, il suffit d'aller chercher à l'endrois approprié son adresse (cela s'écrit en une seule instruction assembleur, "CALL [adresseObj + OFS]")

    Etant donné qu'en C++, on peut faire l'appel d'une méthode sur un objet référence par un pointeur à n'importe quel niveau de la hiérarchie de classe, il est IMPERATIF que la VTable soit complète pour n'importe quel objet de la-dite hiérarchie.
    Un peu de code compilé par un "g++ -S" permet de s'en convaincre...
    En effet, de plus, une recherche récursive necéssiterait une table de symboles (correspondance nom de fonction <--> adresse), une recherche dans cette table, ce qui en plus de rendre la complexité variable, l'augmentrait tout simplement de façon dramatique à tout les coups...

    Voilà, et pour les curieux qui voudraient savoir l'effet du sus-dit "virtual inline", et bien il fonctionne (sous reserve d'optimisation suffisante, sous gcc en tout cas) comme inline lorsque l'appel de méthode se fait sur un objet instancié en variable automatique ou globale, et comme virtual dès qu'il conserne un objet dynamique (pointeur).

    Voili voiloù, j'espère vos doutes et interrogation dissoutes.
    Gaïa n'est pas une marchandise.

Discussions similaires

  1. Réponses: 15
    Dernier message: 08/07/2012, 23h49
  2. Comment appeler une méthode dont le nom est dans un string?
    Par Ireon dans le forum API standards et tierces
    Réponses: 22
    Dernier message: 13/04/2007, 17h22
  3. Appel d'une méthode virtuelles
    Par BIPBIP59 dans le forum C++Builder
    Réponses: 4
    Dernier message: 24/03/2006, 14h00
  4. Réponses: 2
    Dernier message: 31/08/2005, 16h12

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