Как я понимаю, расположение таблицы указателей функций virtual
в объекте зависит от компилятора.
Есть ли какие-либо плюсы/минусы размещения этого указателя в начале объекта или в конце или наоборот?местоположение указателя таблицы виртуальных функций в объекте
ответ
Простое существование таблицы виртуальных функций зависит от компилятора (но все компиляторы делают), а местоположение не обязано ни ... Во всех компиляторах, из которых Я знаю подробности, vptr хранится в начале объекта. Причина в том, что он обеспечивает равномерное местоположение. Рассмотрим иерархию классов:
struct base {
T data;
virtual void f();
};
struct derived : base {
T1 data;
virtual void g();
};
Если vptr хранилась в конце объекта, то это будет после того, как sizeof(T)
байт для объекта полного типа base
. Теперь, когда у вас есть объект полного типа derived
, макет подэлемента base
должен быть совместим с макетом полного объекта base
, поэтому vptr
все равно должен быть sizeof(T)
байтов внутри объекта, который был бы где-то в середина derived
объект (sizeof(T)
с самого начала, sizeof(T1)
до конца). Таким образом, он больше не будет на конце объекта.
Кроме того, при указании this
для виртуального вызова требуется косвенная привязка через таблицу vtable, которая в основном разыменовывает vptr
, добавляя смещение и прыгая в место хранения, хранящееся там. Если vptr
был сохранен в конце объекта, для каждого виртуального вызова было бы дополнительное дополнение к this
перед разыменованием vptr
.
В теории вы могли бы иметь vptr как в конце подобъекта базового класса, так и в полном объекте. Это имело бы смысл: иметь 'Derived' vptr для виртуальных функций, которые не отображаются в' Base'. Но накладные расходы на объект не так хороши. – MSalters
Great Explanation !!! –
Да, это полностью зависит от реализации.
Для простой иерархии наследования он находится в начале объекта, но для сложной иерархии его не будет.
Во всяком случае, любой исходный код, который вы пишете, не должен опираться на то, где он находится, на самом деле любой написанный вами код не должен полагаться даже на существование виртуальной таблицы или указателя виртуальной таблицы.
Стандарт C++ не гарантирует, что виртуальная диспетчеризация будет реализована с помощью виртуальной таблицы и указателя, реализация может быть реализована с использованием другого метода реализации. Однако все основные компиляторы реализуют это посредством механизма указателя таблицы. Важно отметить, что они могут отличаться в точном осуществлении того, где находится указатель и т. д.
Возможный дубликат [Извлечение vptr (указатель на виртуальную таблицу aka VTABLE) из утилиты Objdump?] (Http://stackoverflow.com/questions/10549311/retrieving-vptrpointer-to-virtual-table-aka-vtablefrom- the-objdump-utility) – iammilind