Last active
August 17, 2025 09:32
-
-
Save sunmeat/064c5737e9f4d74fe244b2bccd7c3663 to your computer and use it in GitHub Desktop.
VMT example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <windows.h> | |
| using namespace std; | |
| class Dog | |
| { | |
| // void** __vfptr; | |
| // VPTR - вказівник на таблицю VTABLE (по одному вказівнику на кожен об'єкт!) | |
| // static void* Dog::vftable[2]; | |
| // сама "таблиця" (тільки одна на всі об'єкти!) | |
| public: | |
| char* name; | |
| int age; | |
| /* Dog() | |
| { | |
| // __vfptr = Dog::vftable; // неявне зв'язування вказівника з таблицею | |
| // ... інші явні дії програміста | |
| } */ | |
| virtual void Guard() | |
| { | |
| cout << "Dog::Guard()\n"; | |
| } | |
| virtual void Bark() | |
| { | |
| cout << "Dog::Bark()\n"; | |
| } | |
| static void Print() | |
| { | |
| cout << "Dog::Print()\n"; | |
| } | |
| }; | |
| class Mops : public Dog | |
| { | |
| // успадкований | |
| // void** __vfptr; // VPTR - вказівник на таблицю VTABLE (по одному вказівнику на кожен об'єкт) | |
| // статичні компоненти не успадковуються, - це вже нова таблиця! | |
| // static void* Mops::vftable[2]; // таблиця (одна на клас) | |
| public: | |
| int mops_field; | |
| /* Mops() | |
| { | |
| // __vfptr = Mops::vftable; // неявне зв'язування вказівника з новою таблицею | |
| // ... інші явні дії програміста | |
| } */ | |
| void Guard() // перевизначення методу, тому в "таблиці" - нова адреса | |
| { | |
| cout << "Mops::Guard()\n"; | |
| } | |
| void Bark() | |
| { | |
| cout << "Mops::Bark()\n"; | |
| } | |
| }; | |
| int main() { | |
| setlocale(0, "UKR"); | |
| Mops m; | |
| cout << "Адреса об'єкта m типу Mops: "; | |
| cout << &m << "\n"; | |
| // тут можна встановити брейкпойнт | |
| // і перевірити вміст об'єкта Mops | |
| ////////////////////////////////////////////////////////////////////// | |
| // псевдокод налаштування VTABLE для класу Dog: | |
| // Dog::vftable[0] = &Dog::Guard; | |
| // Dog::vftable[1] = &Dog::Bark; | |
| Dog* d = new Dog; | |
| // у конструкторі Dog() для динамічно створеного об'єкта відбулося зв'язування VPTR і VTABLE | |
| // __vfptr = Dog::vftable; | |
| d->Guard(); // <--- ми, земляни, пишемо так :) | |
| // але насправді компілятор сюди підставляє щось на кшталт: | |
| // d->__vfptr[0](); // 0 - це індекс методу Guard | |
| d->Bark(); // d->__vfptr[1](); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment