Čtení: 30 minHodnotí se: úloha 3, zkouška

3 Třídy, VMT a RTTI

Po přečtení umíš
  • poznat rozložení objektu a volání přes VMT
  • najít konstruktor podle přiřazení VMT
  • číst hierarchii tříd z RTTI

3.1 Ukázka: virtuální volání

mov  eax, [ebp+8]     ; this
mov  edx, [eax]       ; VMT je první pole objektu
mov  eax, [ebp+8]
push eax
call dword ptr [edx+8]   ; třetí metoda

Dvojitá dereference a volání přes offset je podpis virtuálního volání. Offset 8 je třetí položka VMT.

3.2 Objekty

Struktura leží v paměti se zarovnáním a vycpávkou. Dědičnost skládá potomka za předka. Polymorfní třída má jako první skrytý ukazatel pVMT.

Definice 3.2 (VMT)

Tabulka ukazatelů na virtuální metody třídy. Konstruktor ji přiřadí do this->pVMT.

Jak najít konstruktor: hledej odkazy na VMT. Funkce, která ji zapisuje na [this], je konstruktor nebo destruktor. U předků se přiřazení opakuje, protože se volají konstruktory po řadě, a u optimalizovaného kódu mohou být inlinované.

3.3 RTTI

Před VMT, na vfptr[-1], leží ukazatel na _RTTICompleteObjectLocator. Z něj vede cesta na popis typu se jménem a na hierarchii tříd. dynamic_cast a typeid z těchto dat žijí.

Když RTTI existuje, dá ti názvy tříd a jejich předky. Bez ní zbývá dedukce z konstruktorů.

Varování 3.3 (Nástroje nejsou důkaz)

U úlohy 3 nestačí výpis nástroje. Musíš interpretovat, co vidíš, a argumentovat, proč hierarchie platí a jiná ne.

3.4 Kvíz

Kvíz

1. Kde obvykle leží pVMT?
2. Volání call [edx+0Ch] je která metoda VMT v 32 bitech?
3. Kde najdeš _RTTICompleteObjectLocator?
4. Jak ověříš, že funkce je opravdu konstruktor?
Ukázat řešeníPřiřazuje VMT do [this], běží po alokaci objektu, případně volá konstruktor předka a inicializuje pole. Destruktor přiřazuje VMT také, ale běží před uvolněním.

3.5 Tahák

Tahák
  • mov edx, [eax] + call [edx+n] = virtuální volání, index n / 4.
  • Konstruktor zapisuje VMT na [this].
  • vfptr[-1] → RTTI → jména a hierarchie.
  • Interpretuj, nekopíruj výpis nástroje.

Zdroje

  • rev03cz: rozložení v paměti strany 4–7, dědičnost 8–9, polymorfismus 10–19, RTTI 20–24, dynamic_cast 25–34
  • NI-REV cvičení 5