Точно так же, как все члены структуры C, кроме одного, не могут иметь тот же адрес, что и охватывающий объект, все непустые подобъекты базового класса, кроме одного, не могут иметь тот же адрес, что и полный объект; полиморфный базовый класс (с виртуальными функциями) не является пустым по определению.
Полиморфный базовый подобъект, имеющий тот же адрес, что и производный объект, называется первичным базовым. Производный объект разделяет основу макета vtable и vptr с первичной базой: неявный параметр this
не изменяется.
Примечание. Концепция первичной базы — это концепция домена реализации C++ (например, vtable, vptr...), а не концепция языка C++ (например, базовый класс, виртуальная функция...). Так что, очевидно, это не описано в стандарте C++.
Когда виртуальная функция вызывается динамически через механизм виртуального вызова для объекта неизвестного динамического типа, неявный аргумент this
должен быть настроен на правильное значение, которое является другим значением не первичных баз. Посредник, который это делает, называется преобразователь. В этом случае преобразователь может сделать переход, а не вызов функции, к правильной функции: дополнительная работа выполняется при входе в функцию, и ничего не требуется при выходе из функции.
Другой тип корректировки возникает, когда используется ковариантный тип возвращаемого значения, а производное отношение ковариантного возврата к базовому не является отношением производного к первичному базовому. Очевидно, что этот тип преобразователя не выполняет переход, он выполняет вызов функции, поскольку корректировка ковариации происходит при выходе из функции.
person
curiousguy
schedule
01.03.2018
Here’s the solution: the compiler creates a ‘thunk’ method that corrects this and then calls the ‘real’ method. The address of the thunk method will sit under Child’s Father vtable, while the ‘real’ method will be under Child’s vtable.
Это также играет роль в этом предложенииIn other words, for a given Child c;: (void*)&c != (void*)static_cast<Father*>(&c)
, которое показывает вам, почему указательthis
должен быть скорректирован. - person PeterT   schedule 27.02.2018