Находится ли когда-либо vptr не в начале объекта?

Согласно MSDN, __RTDynamicCast () функция используется для реализации dynamic_cast в Visual C ++. Одним из его параметров является LONG VfDelta это описывается как «смещение указателя виртуальной функции в объекте».

AFAIK vptr всегда находится в начале объекта, поэтому смещение всегда будет равно нулю. Я внимательно посмотрел на разборку различных фрагментов кода с использованием dynamic_cast и я никогда не видел ничего, кроме нуля, передаваемого вместо этого параметра.

Является vptr когда-нибудь находился где-нибудь, кроме объекта? Может ли это смещение быть ничем, кроме нуля?

3

Решение

В случае множественного наследования существует более одного vptr и вам нужно offset, Посмотрите здесь: http://hacksoflife.blogspot.com/2007/02/c-objects-part-3-multiple-inheritance.html

5

Другие решения

Я не знаю, что делает Microsoft, но не всегда верно, что указатель vtable находится со смещением ноль. Примером случаев, когда этого не может быть, является множественное наследование (особенно, если задействованы виртуальные базовые классы).

Редактировать:

Я немного дополню это примерами.

Если первая база или класс не имеют vtbl, у производного класса не будет указателя vtbl со смещением 0 (такое наследование является плохой практикой, но разрешено языком).

Если существует виртуальная база, производный класс обычно будет иметь указатель на виртуальную базу со смещением 0, а не указатель vtbl.

2

Эта функциональность используется при выходе из виртуального наследования (подумайте о диаграмме наследования алмазов). Это смещение является смещением самого класса внутри объекта.

Если B и C получаются из A, а D вытекает из обоих.

   A
/   \
B     C
\   /
D

Тогда B и C могут быть в любом порядке в D. Именно здесь смещение вступает в действие. Поэтому, когда вы динамически передаете объект типа A типу B, он может отличаться в зависимости от того, является ли экземпляр типа B или D.

Наконец, чтобы проиллюстрировать, здесь возможен макет другого класса

Class B:  Class C:   class D:
| A |      | A |     | A |
| B |      | C |     | C |
| B |
| D |

В этом случае смещение таблицы виртуальных функций B может быть либо в 0 (случай экземпляра B), либо sizeof (A) + sizeof (C) (случай экземпляра D)

1
По вопросам рекламы [email protected]