TGViewer
C/C++ | Вопросы собесов C/C++ | Вопросы собесов @easy_c_plus · 4.19K subscribers
Post #2187 716
🤔 Как работает виртуальность в C++?

Виртуальность позволяет осуществлять полиморфизм — важную концепцию объектно-ориентированного программирования, которая позволяет объектам производных классов быть обработанными через указатели или ссылки на базовый класс. Это достигается с помощью виртуальных функций, которые определяются в базовом классе и могут быть переопределены в производных классах.

🚩Виртуальные функции

Виртуальная функция определяется в базовом классе с ключевым словом virtual. Производный класс может переопределить эту функцию.
class Base {
public:
virtual void display() const {
std::cout << "Display from Base" << std::endl;
}
};

class Derived : public Base {
public:
void display() const override {
std::cout << "Display from Derived" << std::endl;
}
};


🚩Как работает vtable и vptr

🟠vtable (виртуальная таблица)
Это таблица указателей на виртуальные функции класса. Каждый класс, содержащий виртуальные функции, имеет свою собственную vtable. В vtable хранятся адреса функций, которые должны быть вызваны для объектов данного класса.

🟠vptr (указатель на vtable)
Это скрытый указатель в каждом объекте класса, содержащего виртуальные функции. Он указывает на vtable соответствующего класса. Когда объект создается, vptr инициализируется, указывая на vtable его класса.

#include <iostream>

class Base {
public:
virtual void display() const {
std::cout << "Display from Base" << std::endl;
}
virtual void show() const {
std::cout << "Show from Base" << std::endl;
}
};

class Derived : public Base {
public:
void display() const override {
std::cout << "Display from Derived" << std::endl;
}
};

int main() {
Base* b = new Derived();
b->display(); // Вызовет Derived::display() благодаря vtable
b->show(); // Вызовет Base::show() поскольку она не переопределена

delete b;
return 0;
}


🚩Процесс вызова виртуальных функций

🟠При компиляции
Компилятор создает vtable для каждого класса, содержащего виртуальные функции. Компилятор также добавляет скрытый vptr в каждый объект класса, который инициализируется для указания на соответствующую vtable.

🟠При выполнении
Когда вызывается виртуальная функция через указатель или ссылку на базовый класс, программа использует vptr для доступа к vtable и вызова правильной версии функции. Это обеспечивает динамическое разрешение вызова функции (runtime polymorphism).

🚩Полиморфизм и наследование

Полиморфизм позволяет использовать базовые указатели или ссылки для работы с производными объектами, что делает код более гибким и расширяемым.
void callDisplay(const Base& obj) {
obj.display();
}

int main() {
Base b;
Derived d;

callDisplay(b); // Вызовет Base::display()
callDisplay(d); // Вызовет Derived::display()

return 0;
}


Ставь 👍 и забирай 📚 Базу знаний
More from @easy_c_plus
  1. Oct 13, 2026🤔 Расскажите про ключевое слово _fastcall? Это соглашение о вызове функций, используемое…
  2. Oct 13, 2026Post #2566
  3. Oct 12, 2026🤔 Какие есть уровни exception гарантий? 1. No-throw Guarantee: метод или операция не выбр…
  4. Oct 12, 2026🤔 Какая сложность поиска в set и unordered_set? Контейнеры set и unordered_set представля…
  5. Oct 11, 2026Post #2563
  6. Oct 11, 2026🤔 Как проверять равенство двух float? Равенство двух float проверяется с учётом допустимо…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →