Вопрос по c++ – Как работают Vtable of Virtual

4

У меня есть небольшое сомнение в виртуальной таблице: всякий раз, когда компилятор встречает виртуальные функции в классе, он создает Vtable и размещает там адрес виртуальных функций. Это происходит аналогично для другого класса, который наследует. Создает ли он новый указатель в каждом классе, который указывает на каждый Vtable? Если нет, то как он обращается к функции Virtual, когда создается новый экземпляр производного класса и назначается базовому PTR?

возможный дубликатVirtual Table C++ Bo Persson

Ваш Ответ

3   ответа
6

Каждый раз, когда вы создаете класс, который содержит виртуальные функции, или вы производный от класса, который содержит виртуальные функции, компилятор создает уникальный VTABLE для этого класса.

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

Затем он помещает VPTR в класс. Существует только один VPTR для каждого объекта при использовании простого наследство VPTR должен быть инициализирован так, чтобы указывать на начальный адрес соответствующего VTABLE. (Это происходит в конструктор.) После того, как VPTR инициализирован для правильного VTABLE, объект в эффект & # x201C; знает & # x201D; какой это тип. Но это самопознание ничего не стоит если он не используется в точке, вызывается виртуальная функция. Когда вы вызываете виртуальную функцию через адрес базового класса ( ситуация, когда компилятор не имеет всей информации необходимо выполнить раннее связывание), что-то особенное происходит. Вместо того, чтобы выполнять типичный вызов функции, который просто CALL на языке ассемблера по определенному адресу, компилятор генерирует другой код для выполнения вызова функции.

Как я уже сказал, компилятор создает уникальный VTABLE для класса и его производного класса.
Как насчет VPTR для VTABLE? Как он работает, когда вы создаете экземпляр производного класса и присваиваете базовый ptr? Naruto
Когда вы делаете виртуальный вызов функции через указатель базового класса (то есть когда вы делаете полиморфный вызов), компилятор незаметно вставляет код для извлечения VPTR и поиска адреса функции в VTABLE, вызывая, таким образом, правильную функцию и вызывая позднее связывание иметь место.
Итак, вы хотите сказать, как. Только один VPTR указывает на конкретную таблицу при создании объекта, а не при назначении прав. Но он всегда будет присутствовать в базовом классе. Naruto
3

Всякий раз, когда программа компилирует виртуальную таблицу для каждого класса, создается очевидный факт, что виртуальные таблицы создаются для каждого класса. Во время выполнения, когда объект создан, компилятор назначает объекту vptr, который указывает на виртуальную таблицу для определенного класса & apos; объект. Короче говоря, vptr создается для каждого объекта.

4

Для каждого класса с виртуальными функциями создается таблица vtable. Затем, когда объект класса с жизнеспособным объектом создается с использованием конструктора, конструктор копирует соответствующую таблицу в объект. Таким образом, каждый объект имеет указатель на свою vtable (или в случае множественного наследования, при необходимости, Orr для каждой из его vtables.). Компилятор знает, где в объекте находится vtable, поэтому, когда ему нужно вызвать виртуальный метод, он выводит байтовый код для сдерживания vtable, ищет соответствующий метод и переходит по его адресу.

В простом случае одиночного наследования дочерний класс начинается с копии vtable родительского класса, а затем получает переопределенную запись для каждого виртуального метода в дочернем классе, который переопределяет метод родительского класса. (и он также получает новую запись для каждой виртуальной функции в дочерней оболочке, которая делаетnot переопределить метод родительского класса)

Похожие вопросы