#cpp
Почему запрещён кастинг в следующем коде? class Base { }; class Derived : virtual public Base { }; int main() { Base *p = new Derived; static_cast(p); return 0; }
Ответы
Ответ 1
Компилятор не может скастовать Base* к Derived*, потому что он не делает полный анализ кода, а значит не знает как именно расположены типы друг относительно друга. Если существуют только типы Base и Derived, то при касте Base* в Derived* надо добавить смещение в 0 байт, т.к. адреса Derived и Base совпадают. Однако компилятор допускает, что может существовать другие типы, например struct Derived2 : virtual Base { char x[1024]; }; struct MostDerived : virtual Derived2, Derived {}; И Base* p может указывать на объект этого типа. Тогда MostDerived выглядит в памяти так: смещение | что находится 0 | MostDerived 0 | Base 0 | Derived2 0 | char Derived2::x[1024] 1024 | Derived Виртуальный базовый класс Base, находится в Derived2, самом первом базовом классе MostDerived. Т.к. Base - это пустой базовый класс, он не занимает никакого места в памяти. После Derived2 будет располагаться Derived, уже без Base. По этому в этом случае при касте Base* в Derived* надо добавить смещение в 1024 байт. Т.к. компилятор не знает какое именно смещение надо использовать, он не может сделать такой static_cast. По этому для виртуальных базовых типов поддерживается только dynamic_cast, и то, только для типов в которых есть виртуальные функции.
Комментариев нет:
Отправить комментарий