Количество виртуальных таблиц и виртуальных указателей в программе на C ++ - PullRequest
9 голосов
/ 19 января 2012

Допустим, у нас есть программа ниже:

class A
{     public:
      virtual fun(){};
};
class B:public A
{     public:
     virtual fun(){};
};
int main()
{
     A a1;
     B b1;
 }

У меня вопрос, сколько vtables и сколько vptrs будет создано, когда мы запустим эту программу?

Ответы [ 6 ]

13 голосов
/ 19 января 2012

Эта программа может быть оптимизирована так, чтобы она была в точности такой:

int main(){}

Таким образом, «нет» - это возможность.

9 голосов
/ 19 января 2012

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

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

Ключевое слово virtual в B не имеет значения - если функция является виртуальной в базовом классе, она будет виртуальной в производных классах независимо от *. 1006 *

8 голосов
/ 19 января 2012

В основном, 2. Один для class A, один для class B (vftables) и 2 vfptrs, один для a1 и один для b1.

Однако этоне стандартный мандат, так что вы могли бы иметь ни одного.(обычно реализации используют vftables, но это не обязательно.

Примечание @R. Мартиньо Фернандес с включенными оптимизациями, у вас не будет созданных объектов, поэтому vfptrs.

4 голосов
/ 19 января 2012

Обратите внимание, что это строго зависит от реализации.
C ++ Standard не говорит о vptr или vtable, виртуальный механизм исключен как деталь реализации для компиляторов.Практически, компиляторы могут реализовать это без использования vptr или vtable. Однако почти все известные компиляторы реализуют это с использованием vptr и vtable.

Учитывая вышеизложенное, чтобы ответить на ваш вопрос:

Каждый класс будет иметь свою собственную виртуальную таблицу.
В то время как каждый объект имеет свой виртуальный указатель.

3 голосов
/ 04 апреля 2013

Виртуальная таблица будет создаваться только в том случае, если в базовом классе есть хотя бы одна виртуальная функция 1, которая будет в любом случае унаследована от производных классов. Это не имеет значения, даже если вы удалите виртуальное ключевое слово из производного класса B, поскольку вы уже виртуальное веселье () в А. Таким образом, количество виртуальных таблиц будет равно 2 (в расчете на класс), а количество виртуальных ptrs также будет равно 2 в расчете на объект. VTABLE для A --- v_ptr *, A :: fun ()

& VTABLE для B --- V_ptr * (который был унаследован от A), B :: fun () / * B имеют доступ как к A :: fun & B's fun (), но так как мы упомянули A :: fun (), так как виртуальная таблица виртуальной B заполнена самой производной версией функции fun (), которая является ничем иным, как B :: fun (). Надеюсь, это очистит ваше сомнение

1 голос
/ 12 января 2018

Будет 2 vtables, один для класса A и один для класса B .И будет 3 vptrs, один в a1 и два в b1 (один указывает на vtable из класса A и другой указывает на vtable из класса B ).

...