Chaque objet de classe virtuelle a-t-il un pointeur sur vtable?
Est-ce que chaque objet de la classe virtuelle ont un pointeur vers vtable?
Ou seulement l'objet de la classe de base avec fonction virtuelle a?
Où la vtable stockées? le code de la section ou de la section de données de processus?
source d'informationauteur MainID
Vous devez vous connecter pour publier un commentaire.
De toutes les classes avec une méthode virtuelle aura une vtable unique qui est partagée par tous les objets de la classe.
Chaque instance d'objet aura un pointeur vers cette vtable (c'est la façon dont la vtable), généralement appelé un vptr. Le compilateur implicitement génère du code pour initialiser le vptr dans le constructeur.
Remarque que rien de tout cela est mandaté par le langage C++ - une mise en œuvre peut gérer virtuel envoi d'une autre façon si il veut. Cependant, c'est l'application qui est utilisé par chaque compilateur, je suis familier avec. Stan Lippman, livre, "à l'Intérieur de l'Objet C++ Modèle" décrit la façon dont cela fonctionne très bien.
Vtable une instance de classe, c'est à dire, si j'ai 10 des objets d'une classe qui a une méthode virtuelle il y a seulement une vtable qui est partagée entre tous les 10 objets.
Tous les 10 objets dans ce cas, point à la même vtable.
Essayer à la maison:
Une VTable est un détail d'implémentation, il n'est rien dans la définition du langage qui dit qu'il existe. En fait j'ai lu sur d'autres méthodes pour la mise en œuvre des fonctions virtuelles.
MAIS: Toutes les communes de compilateurs (c'est à dire celles que je connais) l'utilisation VTabels.
Alors Oui. Toute la classe qui a une méthode virtuelle ou est dérivée d'une classe (directement ou indirectement) qui a une méthode virtuelle permettra d'avoir des objets avec un pointeur vers une VTable.
Toutes les autres questions que vous vous posez dépend du compilateur/matériel il n'y a pas de vraie réponse à ces questions.
Toutes les classes virtuelles ont généralement une vtable, mais il n'est pas requis par la norme C++ et la méthode de stockage dépend du compilateur.
Pour répondre à la question au sujet de laquelle les objets (instances) ont vtables et où, il est utile de penser quand vous avez besoin d'une vtable pointeur.
Pour toute hiérarchie d'héritage, vous avez besoin d'une vtable pour chaque ensemble de fonctions virtuelles définies par une classe particulière dans la hiérarchie. En d'autres termes, étant donné la suivante:
Comme un résultat, vous avez besoin de cinq vtables: A, B, C, D, et E tous besoin de leur propre vtables.
Ensuite, vous devez savoir ce que vtable d'utiliser un pointeur ou d'une référence à une classe particulière. E. g., un pointeur vers un, vous devez savoir assez sur la mise en page de sorte que vous pouvez obtenir une vtable qui vous indique où l'expédition A::f(). Un pointeur vers B, vous avez besoin de savoir assez sur la mise en page de B pour l'expédition B::f() et B::g(). Et ainsi de suite et ainsi de suite.
Une possible mise en œuvre pourrait mettre une vtable pointeur en tant que premier membre d'une classe. Que signifierait la mise en page d'une instance de A est:
Et une instance de B serait:
Et vous pouvez générer virtuel correct expédition de code à partir de cette mise en page.
Vous pouvez également optimiser la mise en page en combinant vtable des pointeurs de vtables qui ont la même mise en page, ou si l'un est un sous-ensemble de l'autre. Ainsi, dans l'exemple ci-dessus, vous pouvez également mise en page B comme:
Parce que B la vtable de est un sur-ensemble d'Un. B la vtable possède des entrées pour A::f et B::g, et la vtable possède des entrées pour A::f.
Pour être complet, voici comment vous pouvez la disposition de tous les vtables nous avons vu jusqu'à présent:
Et les entrées réelles serait:
Pour l'héritage multiple, vous faire la même analyse:
Et la résultante de ces dispositions serait:
Vous avez besoin d'un pointeur vers une vtable compatible avec Un et un pointeur vers une vtable compatible avec les B, car une référence à C peut être convertie en une référence de A ou B et que vous avez besoin pour l'expédition des fonctions virtuelles à C.
De cela, vous pouvez voir que le nombre de vtable des pointeurs d'une classe a est au moins le nombre de classes racines d'où elle provient (soit directement, soit en raison d'une super-classe). De la racine de la classe est une classe qui a une vtable que de ne pas hériter d'une classe qui dispose également d'une vtable.
L'héritage virtuel jette un peu d'indirection dans le mélange, mais vous pouvez utiliser la même métrique pour déterminer le nombre de vtable des pointeurs.
Chaque objet de type polymorphe aura un pointeur vers Vtable.
Où VTable stockées dépend du compilateur.
Pas nécessairement
À peu près chaque objet qui a une fonction virtuelle aura un v-le pointeur de la table. Il n'a pas besoin d'être un v-le pointeur de la table pour chaque classe qui a une fonction virtuelle que l'objet provient.
De nouveaux compilateurs qui analysent le code suffisamment peut être en mesure d'éliminer les v-tableaux, dans certains cas, cependant.
Par exemple, dans un cas simple: si vous avez seulement une mise en œuvre concrète d'une classe de base abstraite, le compilateur sait qu'il peut changer le virtuel appels régulièrement des appels de fonction, car à chaque fois que la fonction virtuelle est appelée, elle sera toujours résoudre exactement la même fonction.
Aussi, si il ya seulement un couple de différents béton fonctions, le compilateur peut effectivement modifier l'appel-site de sorte qu'il utilise un "si", sélectionnez le droit de béton de la fonction à appeler.
Donc, dans des cas comme celui de la v-table n'est pas nécessaire, et les objets pourriez ne pas en avoir un.