Виртуальные функции и таблица vtable
Реализуйте полиморфизм времени выполнения с помощью виртуальных функций и изучите концепцию vtable.
«Виртуальные функции и таблица vtable» — бесплатный урок C++ Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.
Статическое и динамическое связывание
По умолчанию вызовы членов связываются статически — компилятор выбирает функцию на основе объявленного типа. Для функций virtual вызов связывается динамически на основе фактического типа.
Объявление виртуальной функции
Пометьте функцию как virtual в базовом классе. Производные классы могут переопределить её.
class Shape {
public:
virtual double area() const = 0; // pure virtual
virtual ~Shape() = default;
};
class Circle : public Shape {
double r_;
public:
Circle(double r) : r_(r) {}
double area() const override { return 3.14159 * r_ * r_; }
};Спецификатор override
Добавляйте override к методам производного класса. Компилятор проверяет, действительно ли функция переопределяет виртуальную функцию, и обнаруживает опечатки в сигнатуре.
Спецификатор final
final запрещает дальнейшее переопределение. Используйте его для классов, от которых нельзя наследоваться, или для методов, которые нельзя переопределять повторно.
class Concrete final : public Base { /* ... */ };
class Base {
virtual void f() final; // cannot be overridden
};Вызов через указатель на базовый класс
В этом заключается сила полиморфизма: указатель на базовый класс может вызвать правильный метод производного класса.
Shape* s = new Circle(3.0);
std::cout << s->area(); // 28.27... (Circle::area)
delete s;Понятие таблицы виртуальных функций
У каждого полиморфного класса есть скрытая таблица виртуальных функций — таблица указателей на функции. Каждый объект хранит скрытый указатель на таблицу виртуальных функций своего класса.
Цена виртуальных вызовов
Виртуальный вызов добавляет одно косвенное обращение через таблицу виртуальных функций. В большинстве кода это несущественно. Избегайте виртуальных вызовов во внутренних циклах, если измерения показывают, что они стали узким местом.
Чисто виртуальные функции
Добавьте = 0, чтобы сделать функцию чисто виртуальной. Производные классы должны переопределить её, чтобы их можно было создавать. Класс становится абстрактным.
Виртуальные деструкторы
Если у класса есть хотя бы одна виртуальная функция или объекты этого класса предполагается удалять через указатель на базовый класс, объявите виртуальный деструктор. В противном случае деструктор производного класса не будет вызван.
class Base {
public:
virtual ~Base() = default; // safe to delete through Base*
};Полиморфизм с интеллектуальными указателями
Храните полиморфные объекты с помощью интеллектуальных указателей на базовый класс. Интеллектуальный указатель корректно выполняет уничтожение объекта.
std::unique_ptr<Shape> s = std::make_unique<Circle>(3.0);Срезка: повторный разбор
Передача объекта производного класса по значению в функцию, ожидающую базовый класс, отбрасывает часть производного класса. Для полиморфных параметров используйте ссылки или указатели.
Компромисс производительности
Виртуальные функции обеспечивают гибкость при небольших затратах во время выполнения. Шаблоны дают полиморфизм времени компиляции без затрат во время выполнения — выбирайте подход в зависимости от того, нужен ли полиморфизм во время выполнения.
Быстрая проверка
Почему у полиморфного базового класса должен быть виртуальный деструктор virtual?
Итоги
Виртуальные функции обеспечивают полиморфизм времени выполнения через таблицу виртуальных функций каждого класса. Помечайте переопределения с помощью override, а дальнейшее наследование запрещайте с помощью final. Всегда объявляйте виртуальный деструктор у полиморфных базовых классов.
Часто задаваемые вопросы
Урок «Виртуальные функции и таблица vtable» бесплатный?
Да — полный текст урока «Виртуальные функции и таблица vtable» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.
Чему я научусь в уроке «Виртуальные функции и таблица vtable»?
Реализуйте полиморфизм времени выполнения с помощью виртуальных функций и изучите концепцию vtable. Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C++ Academy?
Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Виртуальные функции и таблица vtable»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C++ Academy?
Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Одиночное и множественное наследование
- Виртуальные функции и таблица vtable
- Абстрактные классы и чисто виртуальные методы
- Наследование и композиция: компромиссы