#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 небольшая, но значительная.