C gcc 9.3.0 идентификатор типа производного указателя всегда возвращает идентификатор типа (базовый класс *), но dynamic_cast работает нормально

#c #gcc #rtti #dynamic-cast #typeid

#c #gcc #rtti #динамическое приведение #typeid

Вопрос:

Есть несколько похожих сообщений, вот мой минимальный код обращения:

 bool useDerived=true;
BaseClass* maker;
if (useDerived) {
    maker = new DerivedClass();
}
else {
    maker = new BaseClass();
}
if (typeid(maker) == typeid(DerivedClass*)) {
    cerr << "is derived typen";
}
else {
    cerr << "not derived typen";
}
DerivedClass* x = dynamic_cast<DerivedClass*>(maker);
if (x == nullptr) {
    cerr << " cannot cast back to derivedn";
}
else {
    cerr << " cast to derived OKn";
}
 

Результат:

 not derived type
cast to derived OK
 

Я что-то здесь упускаю? Я включаю <typeinfo> заголовок. Может ли это быть ошибка, зависящая от версии компилятора?

The DerivedClass является производным от BaseClass , и DerivedClass реализует несколько виртуальных функций из BaseClass . Идея использовать typeid основана на разделе блога: Typeid как более быстрый dynamic_cast .

Ответ №1:

typeid в этом случае вычисляется статически. Вы должны были разыменовать, чтобы присвоить ему значение glvalue полиморфного типа вместо некоторого типа указателя.

Эта строка:

 if (typeid(maker) == typeid(DerivedClass*)) {
 

должно быть:

 if (typeid(*maker) == typeid(DerivedClass)) {
 

Комментарии:

1. Это решение, которое я искал. Решил мою проблему.

Ответ №2:

Здесь нет ошибки.

typeid() вычисляется во время компиляции. BaseClass* и DerivedClass* являются двумя совершенно разными типами указателей, поэтому сравнение их соответствующих std::type_info структур никогда не будет сравниваться как равные.

dynamic_cast вычисляется во время выполнения. Приведение BaseClass* указателя к DerivedClass* указателю вызовет поиск RTTI для поиска и возврата указателя на ту DerivedClass часть объекта, на которую указывает BaseClass* указатель. Если объект не будет реализован DerivedClass , dynamic_cast вернется nullptr .

Комментарии:

1. В этом случае typeid вычисляется статически. Ошибка OP небольшая, но значительная.