Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Last active June 19, 2026 14:23
Show Gist options
  • Select an option

  • Save sunmeat/064c5737e9f4d74fe244b2bccd7c3663 to your computer and use it in GitHub Desktop.

Select an option

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 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