typeid — Как определить фактический тип объекта во время выполнения в C ++;

Допустим, у нас есть иерархия классов. Внизу у нас есть База, а вверху Производная.
Как определить класс объекта, даже если он преобразован в указатель базового класса.

Base* b = new Derived():

typeid(b).name(); // i want this to tell me that this is actually derived not base object

Есть ли способ, кроме ручной реализации строкового поля или такой и виртуальной функции get?

PS: я говорю о компилятор-независимом решении

14

Решение

убедитесь, что в базовом классе есть хотя бы один виртуальный метод, включите <typeinfo> и использовать ваш текущий код просто с помощью дополнительной разыменования, typeid(*b).name(),


мимоходом, обратите внимание, что typeid call — это единственное место в C ++, где вы можете разыменовать нулевой указатель с четко определенным поведением, что подразумевает, что он может вызвать исключение:

C ++ 11 §5.2.8 / 2:
«Если выражение glvalue получается путем применения унарного * оператор к
указатель и указатель является нулевым значением указателя (4.10), typeid выражение бросает std::bad_typeid исключение (18.7.3). »

26

Другие решения

Если все, что вы хотите сделать, это найти, если b на самом деле указывает на DerivedПросто используйте dynamic_cast():

if (dynamic_cast<Derived*>(b)) { ... }

dynamic_cast возвращает нулевой указатель, если фактический тип времени выполнения объекта, на который указывает b не является Derived (или класс, полученный из Derived). в отличие от name() член std::type_infoэто инвариант компилятора.

Обратите внимание, что это работает только если Base имеет по крайней мере один виртуальный член функции. Как бы то ни было, так как вы управляете типами, производными от него, через базовый указатель, поэтому у него должен быть виртуальный деструктор.

8

По вопросам рекламы [email protected]