Ваш подход имеет неопределенное поведение при использовании возвращенного указателя, потому что reinterpret_cast
не может вообще приводить указатели в иерархии наследования. Он будет работать правильно, только если производный объект взаимозаменяем с указателем с объектом базового класса. В частности, это относится только к стандартным макетам классам и классам с виртуальными функциями, никогда не стандартным макетам. reinterpret_cast
не меняет адрес указателя, он просто переосмысливает это.
То, что вы, вероятно, намеревались использовать, это static_cast
, который делает приведение иерархия классов, корректируя указатель по мере необходимости, предполагая, что объект-указатель на самом деле имеет производный тип (который вы проверили с помощью теста).
В качестве альтернативы вы можете получить тот же эффект, используя dynamic_cast
, который в отличие от static_cast
сам проверяет производный тип и возвращает нулевой указатель, если объект не имеет производного типа:
auto d = dynamic_cast<T*>(b);
if(d)
return d;
В отличие от показанного подхода, dynamic_cast
не требует тип наиболее производный должен быть равен T
, просто в иерархии наследования самого производного объекта есть (уникальный, public
) T
.
В общем, вам следует избегать подобных конструкций. Необходимость знать производный тип объекта обычно указывает на то, что вы неправильно спроектировали виртуальный интерфейс. Все пользователи указателя базового класса должны только вызывать функции в этом интерфейсе и не заботиться о производном типе.