Last active
June 19, 2026 14:23
-
-
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 Pug : public Dog { | |
| // успадкований | |
| // void** __vfptr; | |
| // статичні компоненти не успадковуються, - це вже нова таблиця! | |
| // static void* Mops::vftable[2]; // таблиця (одна на клас) | |
| public: | |
| int mops_field; | |
| /* Pug() | |
| { | |
| // __vfptr = Pug::vftable; // неявне зв'язування покажчика з новою таблицею | |
| // ... інші явні дії програміста | |
| } */ | |
| void guard() // перевизначення методу, тому в "таблиці" - нова адреса | |
| { | |
| cout << "Mops::Guard()\n"; | |
| } | |
| void bark() { | |
| cout << "Mops::Bark()\n"; | |
| } | |
| }; | |
| int main() { | |
| Pug m; | |
| cout << "Адреса об'єкта m типу Pug: "; | |
| 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](); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment