Вызов виртуальной функции во время выполнения (стандартный c ++) - PullRequest
1 голос
/ 22 ноября 2011

vtable - это издержки во всех базовых / производных классах, когда базовый класс имеет виртуальную функцию.vtable должен содержать массив указателей на функции virtual.Также vtable - это «один на класс», а не «один на объект».

Теперь представьте, что создается объект такого класса.Он получит свежую копию virtual функций класса в какой-то ячейке памяти во время выполнения.Поскольку vtable представляет собой набор указателей функций, он будет обновлен, чтобы отразить это.Если будет создан другой объект того же класса, он снова получит свежую копию функций virtual в другом месте памяти

Поскольку vtable имеет значение «один на класс», а не «один»за экземпляр "как он будет указывать на правильное местоположение для разных экземпляров?

Ответы [ 3 ]

8 голосов
/ 22 ноября 2011

Все просто ... сама vftable - one-per-class, указатель - one-per-instance.Два экземпляра одного типа будут иметь указатель vftable, указывающий на одно и то же местоположение.

class A
{
   virtual void foo();
   virtual void goo();
}

class B : public A
{
   virtual void foo();
}

В памяти у вас будет:

vftable for A:  

+----------+---------+
|   0x01   |  0x02   |
+----------+---------+
  &A::foo()  &A::goo()

vftable for B:

+----------+---------+
|   0x11   |  0x12   |
+----------+---------+
  &B::foo()  &A::goo()

Предположим, вы создали два объекта:

A a;
B b;

Первым членом a будет:

vftableptr: 0x01

Первым членом b будет

vftableptr: 0x11

В общем, полиморфизм реализуется, получая адрес vftableдобавление функции смещения (например, если мы вызываем goo(), смещение равно 1) и переход к этому месту.Поскольку объекты имеют разные типы, они будут указывать на разные местоположения, хотя таблицы vftable (которые различаются) могут содержать похожие элементы.

ВАЖНОЕ ПРИМЕЧАНИЕ: значения являются поддельными, смещение не 1 ни адреса 0x01 и т. Д., Я выбрал их, чтобы сделать точку.

5 голосов
/ 22 ноября 2011

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

3 голосов
/ 22 ноября 2011

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

...