Où dans la mémoire est vtable stocké?Où la mémoire est-elle stockée vtable?
Répondre
Dépend du compilateur.
Dans VC++, le pointeur vtable stocké au début de l'allocation d'objet, avant toute donnée de membre. (À condition que votre classe comporte au moins une fonction de membre virtuel.)
Il peut également y avoir plusieurs pointeurs vtable, si votre classe multiplie-hérite d'autres classes avec vtables.
Les vtables eux-mêmes sont alloués de manière statique quelque part dans votre espace d'adressage.
Ensuite, la mise en page de l'objet ressemble (pour une instance de C):
A's VTable ptr
A's member variables.
B's Vtable ptr
B's member variables.
C's member variables.
pour le heirarchy
class A {
virtual Ax() {}
int a, b;
};
class B {
virtual Bx() {}
int c, d;
};
class C : public A, public B {
int foo, bar;
};
Le VPTR généralement au début de l'objet (Imperfect C++, Backyard Hotrodding C++) mais cela n'est pas garanti dans le standard ré. L'utilisation de vptrs et de vtables n'est pas garantie dans la norme. Si vous avez vraiment besoin de savoir où il se trouve, il est courant d'utiliser COM, XPCOM, UNO, etc. pour implémenter un endroit où quelque chose comme un vptr est situé Utilise les.
Les liaisons CM ++ et CORBA C++ que j'ai utilisées laissent le placement de la vtable au compilateur C++. –
Merci, j'ai supprimé CORBA de la liste –
Vtable? Quel vtable? Le standard C++ ne mentionne pas de vtable. Chaque compilateur peut implémenter des fonctions virtuelles comme bon lui semble. Et cela inclut placer le vtable n'importe où il aime.
Je crois que le vtable peut être n'importe où sauf à l'adresse de départ de l'objet. Ma compréhension est que l'adresse du premier élément est aussi l'adresse de départ de la structure. –
Non, ce n'est pas une exigence. C'est le cas pour les types POD, mais les types POD n'ont pas de vtable, donc c'est un non-problème là. Pour les types non-POD, il n'y a aucune garantie que l'adresse de la structure est la même que l'adresse du premier élément. – jalf
Chaque instance qui inclut une fonction virtuelle a un pointeur de fonction virtuelle qui pointe vers la table de fonction virtuelle (vbtl), nous avons seulement pu localiser le vtbl à travers l'instance. ou vous pouvez utiliser l'objdump pour lire le symbole du fichier ELF, peut-être que vous pouvez trouver la réponse. J'espère que l'exemple suivant peut vous aider.
#include <iostream>
#include <stdio.h>
typedef void (*fun_pointer)(void);
using namespace std;
class Test
{
public:
Test()
{
cout<<"Test()."<<endl;
}
virtual void print()
{
cout<<"Test::Virtual void print()."<<endl;
}
virtual void print2()
{
cout<<"Test::virtual void print2()."<<endl;
}
};
class TestDrived:public Test
{
public:
TestDrived()
{
cout<<"TestDrived()."<<endl;
}
virtual void print()
{
cout<<"TestDrived::virtual void print()."<<endl;
}
virtual void print2()
{
cout<<"TestDrived::virtual void print2()."<<endl;
}
void GetVtblAddress()
{
cout<<"vtbl address:"<<(int*)this<<endl;
}
void GetFirstVtblFunctionAddress()
{
cout<<"First vbtl function address:"<<(int*)*(int*)this+0 << endl;
}
void GetSecondVtblFunctionAddress()
{
cout<<"Second vbtl function address:"<<(int*)*(int*)this+1 << endl;
}
void CallFirstVtblFunction()
{
fun = (fun_pointer)* ((int*) *(int*)this+0);
cout<<"CallFirstVbtlFunction:"<<endl;
fun();
}
void CallSecondVtblFunction()
{
fun = (fun_pointer)* ((int*) *(int*)this+1);
cout<<"CallSecondVbtlFunction:"<<endl;
fun();
}
private:
fun_pointer fun;
};
int main()
{
cout<<"sizeof(int):"<<sizeof(int)<<"sizeof(int*)"<<sizeof(int*)<<endl;
fun_pointer fun = NULL;
TestDrived a;
a.GetVtblAddress();
a.GetFirstVtblFunctionAddress();
a.GetSecondVtblFunctionAddress();
a.CallFirstVtblFunction();
a.CallSecondVtblFunction();
return 0;
}
VPTR et Vtable sont stockés dans le segment des données ...
Vtable est comme un tableau de pointeur de fonction.
Vtable et Vptr créent au moment de la compilation ce qui obtiendra de la mémoire à l'exécution et les entrées vtable sont des adresses de fonctions virtuelles.
Chaque objet d'une classe contenant une fonction virtuelle aura un pointeur supplémentaire qui pointe vers Virtual Table est appelé pointeur virtuel.
Chaque fois que nous appelons une fonction virtuelle en utilisant un objet, d'abord le Vptr corrospondant lira la fonction de Vtable au moment de l'exécution et finalement la fonction sera appelée.
- 1. erreur vtable. "vtable for ETRun", référencé par:
- 2. virtual function - vtable
- 3. procédure stockée Mysql où la clause
- 4. C++ Héritage/questions VTable
- 5. C++ d3d hooking - COM vtable
- 6. Où réside la mémoire allouée dynamiquement?
- 7. Où est la fuite de mémoire?
- 8. Où est la fuite de mémoire ici?
- 9. Où est passée toute la mémoire?
- 10. Où est la fuite de mémoire?
- 11. Où est allouée la mémoire dynamique?
- 12. Quelle est Vtable en C++
- 13. La procédure stockée SQL Sybase consomme trop de mémoire
- 14. Où sera la valeur de session sera stockée dans PHP
- 15. Résolution de vtable C++ avec héritage virtuel
- 16. C++ - référence non définie à `vtable
- 17. Qu'est-ce que 'v' dans vtable?
- 18. différence entre la mémoire de la pile et la mémoire de tas
- 19. Où est la fuite de mémoire dans ce C++?
- 20. Où la mémoire d'un vecteur C++ local est-elle allouée?
- 21. Où sont utilisés les algorithmes de gestion de la mémoire?
- 22. Comment savoir où va ma mémoire
- 23. .NET Taille de la mémoire
- 24. Où sont stockées les méthodes en mémoire?
- 25. Augmenter la mémoire pour la mémoire partagée
- 26. Comment utiliser le vtable pour déterminer le type de classe
- 27. Où est stockée une application "Je suis désactivée" sur Windows?
- 28. Comment peut-on inspecter une vtable dans Visual C++?
- 29. g ++ erreur de lien - typeinfo, mais pas vtable
- 30. Existe-t-il une relation entre Virtual destructor et Vtable?
Je pense que vous parlez de vptr, c'est-à-dire des pointeurs vers vtables. Vtables eux-mêmes sont généralement stockés dans le segment de données statique, car ils sont spécifiques à la classe (par rapport à l'objet). –
En effet, j'ai modifié mon post :) –
La mise en page d'objet est pour une instance de C, non? (Par opposition à A, B et C) – Niklas