Несмотря на то, что это определенная реализация, похоже, не является реальным выбором.
Прежде всего, мы можем видеть, что у вас эфир должен быть vptr
или встроенный vtable
. Позже это означает, что вам нужно будет скопировать vtable
на конструкцию, и он потребляет больше памяти, но будет иметь преимущество избежать одного разыменования указателя при каждом вызове метода. Вероятно, есть хорошие аргументы для них обоих в зависимости от ситуации - большинство реализаций выбрали более низкое время строительства и общее потребление памяти вместо экономии времени отправки.
При выборе метода vptr
мы видим, что мы должны поддерживать двоичную совместимость макета базового и производного классов. Прежде всего, мы можем достичь этого (часто) используя один vptr
, этот vptr
должен по соображениям совместимости жить в самом базовом классе.
При использовании простого наследования наиболее прямым способом преобразования между производным и базовым классом является сохранение значения указателя, которое будет означать, что макет должен быть сначала поля для базового класса, за которым следуют добавочные производные классы. к нему.
Теперь мы довольно близки к причине, почему сначала поставить vptr
. Он просто должен быть рядом с началом объекта, поскольку он должен жить в самой основной части объекта.
По этой причине мы положим его на смещение 0, возможно, это согласованное смещение, доступное для всех классов. У вас просто нет гарантии, что есть какие-либо данные, которые можно было бы разместить до vptr
.
Ввод vptr
со смещением 0 имеет некоторые преимущества. Если вы знаете, что объект имеет vptr
, вы знаете, что вам нужно будет посмотреть на смещение 0, не зная тип объекта (больше, чем у него есть vptr
). Это может пригодиться для некоторых целей отладки (vtable
часто содержит достаточно информации для вывода фактического типа).Особенно это делает typeid
и аналогично проще для реализации, так как вам нужно только посмотреть на те же смещения, чтобы получить узел type_info
через предопределенные смещения, что означает, что вы можете использовать фактический код для typeid
.
Является ли поведение «vptr, доступным по первому байту объекта», различным для ОС? –
Это зависит от реализации. –
* «Мы знаем, что если класс имеет виртуальные функции, то его vptr можно получить с адресом первого байта своего объекта« *. Нет, нет. –