Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Last active August 17, 2025 09:32
Show Gist options
  • Save sunmeat/064c5737e9f4d74fe244b2bccd7c3663 to your computer and use it in GitHub Desktop.
Save sunmeat/064c5737e9f4d74fe244b2bccd7c3663 to your computer and use it in GitHub Desktop.
VMT example
#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