Quand la vtable est-elle utilisée?

La table vtable est-elle utilisée uniquement pour les recherches de fonctions virtuelles ou est-elle utilisée pour les recherches de fonctions membres normales?

Techniquement, il s’agit d’un détail d’implémentation. La norme C ++ ne dit rien sur vtables ou vptr.

Mais en règle générale, un compilateur choisira d’utiliser le mécanisme vtable / vptr uniquement lorsqu’une fonction membre est appelée dans un sens polymorphe (c’est-à-dire via un pointeur / un référène sur la classe de base). Si, au moment de la compilation, il sait quoi faire, l’indirection n’est pas nécessaire.

Seulement pour les recherches de fonctions virtuelles. Une fonction membre non virtuelle ne nécessite pas beaucoup de spécial – c’est juste une fonction normale qui le reçoit comme paramètre caché.

La norme ne dicte pas la manière dont l’inheritance est implémenté, donc une table virtuelle n’existe pas nécessairement. Mais pour autant que je sache, tous les principaux compilateurs actuels utilisent uniquement vtables pour appeler des fonctions virtuelles.

dynamic_cast utiliserait également la vtable, je crois.

Autant que je sache, la vtable est créée (et donc utilisée) lorsque la méthode appelée est spécifiée en tant que Virtual. Si c’est virtuel, alors il utilisera la vtable, si ce n’est pas virtuel, alors il sera lié statiquement.

Cette détermination est faite au moment de la compilation.

Cela dépend toujours de la mise en œuvre, mais la plupart des compilateurs utiliseront vtable lorsque:

  • virtual fonction virtual est appelée;
  • lors de l’utilisation de dynamic_cast, les adresses de vtables sont utilisées. La vtable réelle n’est pas utilisée, mais elle doit exister pour avoir une adresse.
  • virtual classe virtual -y héritée est en cours d’access.

virtual access virtual classe héritée inclut à la fois les appels de méthode virtuels et non virtuels, mais aussi l’access aux champs et même la diffusion de pointeur

 class foo{ public: virtual void bar(){} }; class foo2: public virtual foo{ public: virtual void bar2(){} }; int main(int argc, char *argv[]) { foo2* f2= new foo2(); f2->bar(); foo* f1 = f2; } 

Ligne foo* f1 = f2; lira également vtable (bien que la première vérification soit faite pour f2 == NULL, dans ce cas, f1 sera également NULL).

Et la méthode de recherche de pointeur. Il y a au moins une vérification pour voir si le pointeur pointe sur la fonction de membre virtuel.