Я не верю, что это работает, если вы используете static_cast
, потому что вы не можете static_cast
между двумя совершенно не связанными типами классов.В частности, если у вас есть указатель типа A*
и вы пытаетесь преобразовать его в указатель типа B*
, static_cast
будет успешным только в том случае, если это объявление действительно:
B* ptr(myAPtr);
илиесли B
не является фактически производным от A
(что не является).См. Спецификацию ISO § 5.2.2 для подробностей об особенностях этого.Если мы рассмотрим вышеупомянутое объявление, единственные возможные преобразования, которые могут быть применены здесь во всем §4, - это преобразования в §4.10, и из тех, которые могут быть применимы, это только преобразование из базовых в производные классы (§4.10 / 3), но здесь это не применимо, потому что A
и B
не являются связанными типами.
Единственный приведенный вами тип приведен здесь reinterpret_cast
, и он не выглядиткак это будет работать либо.В частности, поведение приведения к иерархии классов имеет вид (§5.2.10 / 7)
Указатель на объект может быть явно преобразован в указатель на объект другого типа.65) За исключениемчто преобразование r-типа типа «указатель на T1» в тип «указатель на T2» (где T1 и T2 - типы объектов и где требования к выравниванию T2 не более строгие, чем требования к T1) и обратноисходный тип возвращает исходное значение указателя, результат такого преобразования указателя не определен.
Так что сразу нет гарантии, что что-нибудь будет работать, если два объекта имеют разные ограничения выравнивания, иВы не можете гарантировать, что это правда.Но предположим, что вы могли.В этом случае, однако, я считаю, что это на самом деле будет работать правильно!Вот рассуждения.Когда вы вызываете функцию-член объекта B
, тогда срабатывает правило & 5.2.2 / 1), которое говорит, что функция не виртуальная:
[...]в вызове функции-члена обычно выбирается в соответствии со статическим типом выражения объекта.[...]
Хорошо, так что мы по крайней мере вызываем правильную функцию.А как насчет указателя this
?Ну, согласно & 5.2.2 / 4:
[...] Если функция является нестатической функцией-членом, параметр «this» функции (9.3.2) должен быть инициализирован суказатель на объект вызова, преобразованный как бы путем явного преобразования типа (5.4).[...]
Преобразование типов, выполненное в последней части, представляет собой преобразование идентичности из B*
в B*
, поскольку это выбранный тип.Итак, вы вызвали правильную функцию с указателем this
, установленным соответствующим образом.Ницца!Наконец, когда вы вернете reinterpret_cast
к исходному типу, по более раннему правилу вы получите объект A*
, и все пойдет как положено.
Конечно, этоработает, только если объекты имеют одинаковые требования выравнивания , и это не может быть гарантировано.Следовательно, вы не должны этого делать!
Надеюсь, это поможет!