2012-06-07 3 views
5

Как я понимаю, расположение таблицы указателей функций virtual в объекте зависит от компилятора.
Есть ли какие-либо плюсы/минусы размещения этого указателя в начале объекта или в конце или наоборот?местоположение указателя таблицы виртуальных функций в объекте

+0

Возможный дубликат [Извлечение vptr (указатель на виртуальную таблицу aka VTABLE) из утилиты Objdump?] (Http://stackoverflow.com/questions/10549311/retrieving-vptrpointer-to-virtual-table-aka-vtablefrom- the-objdump-utility) – iammilind

ответ

7

Простое существование таблицы виртуальных функций зависит от компилятора (но все компиляторы делают), а местоположение не обязано ни ... Во всех компиляторах, из которых Я знаю подробности, 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.

+0

В теории вы могли бы иметь vptr как в конце подобъекта базового класса, так и в полном объекте. Это имело бы смысл: иметь 'Derived' vptr для виртуальных функций, которые не отображаются в' Base'. Но накладные расходы на объект не так хороши. – MSalters

+0

Great Explanation !!! –

4

Да, это полностью зависит от реализации.
Для простой иерархии наследования он находится в начале объекта, но для сложной иерархии его не будет.
Во всяком случае, любой исходный код, который вы пишете, не должен опираться на то, где он находится, на самом деле любой написанный вами код не должен полагаться даже на существование виртуальной таблицы или указателя виртуальной таблицы.
Стандарт C++ не гарантирует, что виртуальная диспетчеризация будет реализована с помощью виртуальной таблицы и указателя, реализация может быть реализована с использованием другого метода реализации. Однако все основные компиляторы реализуют это посредством механизма указателя таблицы. Важно отметить, что они могут отличаться в точном осуществлении того, где находится указатель и т. д.