Próbuję odświeżyć niektóre rzeczy niskiego poziomu za pomocą wirtualnego stołu i dziedziczenia.Zrozumienie tabeli vtable w klasach pochodnych
Kiedy tworzysz nową klasę, dziedzicząc dwie klasy i dodając nowe funkcje wirtualne, gdzie dokładnie przechowywany będzie vptr?
Wydaje mi się, że kompilator wykonuje "optymalizację vptr" w tym przypadku. Próbuję to rozgryźć.
Przypuśćmy, że mamy następujące konstrukcjom:
struct A
{
int a;
virtual void fa();
};
struct B
{
double b;
virtual void fb();
};
struct C : A, B
{
char c;
virtual void fa();
virtual void fb();
virtual void fc();
};
w przypadku x86 i align = 4, A
i B
w pamięci będzie wyglądać następująco:
+------+------+
A: | vptr | a |
+------+------+
sizeof(A) = 4 + 4 = 8
+------+------+------+------+
B: | vptr | b |
+------+------+------+------+
sizeof(B) = 8 + 8 = 16
Ale gdy próbuję ponownie składaj C
, otrzymuję to:
+------+------+------+------+------+------+------+
C: | vptr | a | vptr | b | c |
+------+------+------+------+------+------+------+
but sizeof(C) = 32
С с;
(C*)&c; // 0x100
(B*)&c; // 0x108
(A*)&c; // 0x100
&c.a; // 0x104
&c.b; // 0x110
&c.c; // 0x118
Tak więc re jest vptr z C
? Mogę przypuszczać, że kompilator scalania różnych tabel wirtualne, ale w takim razie dlaczego sizeof(C)
powraca sizeof(A)
+ sizeof(B)
+ sizeof(alligned_char)
+ sizeof (vptr)
struct D : public C {}
ma tę samą historię (dawny vptr z A
i C
.) - nie nie jest vptr z D
.
Używany kompilator to msvc 2012 x86.
czemu vptr w struct B muszą 8 bajtów? – walker
@walker Wątpię, że tak. To prawdopodobnie trochę wyściółki. – luk32
Możliwy duplikat [Ile vptr będzie obiektem klasy (używa dziedziczenia pojedynczego/wielokrotnego)?] (Https://stackoverflow.com/questions/3342035/how-many-vptr-will-a-object-of- classuses-one-multiple-dziedziczenie-have) – Andrew