class X
{
virtual void func() {};
};
class XX : public X {};
void main()
{
XX *xx = new XX();
X *x = dynamic_cast<X*>(xx);
const type_info &tiXX = typeid(xx);
const type_info &tiX = typeid(x);
XX *xx1 = dynamic_cast<XX*>(x); // ???
delete xx;
}
Попробую сформулировать вопросы.
При восходящем приведении (от производного к базовому) все в порядке.
X *x = dynamic_cast<X*>(xx);
И если посмотреть в дизассемблере, то собственно RTTI для такого
приведения не требуется. Переменной 'x' тупо присваивается значение
переменной 'xx'
А вот при нисходящем уже требуется RTTI, и компилятор предупреждает
что в этой строке
XX *xx1 = dynamic_cast<XX*>(x); // ???
используется dynamic_cast с полиморфичным классом при отключенной
опции /GR-. Включаем эту /GR и все в порядке. В MSDN написано что
эта опция позволяет компилятору добавлять код для проверки типа
объекта в рантайме.
И собственно вопросы:
1. Почему нормально работает оператор 'typeid' даже при отключенной
опции GR, что для 'typeid' не требуется RTTI
const type_info &tiXX = typeid(xx);
const type_info &tiX = typeid(x);
2. Где живет эта информация об RTTI. В таблице виртуальных ф-ий что-то
не увидел я указателя на RTTI. Хотя это вопрос реализации, но все же
интересно.
3. Добавляется ли эта RTTI ко всем полиморфным классам программы или
только к классам, которые используются в dynamic_cast
Хмм....
На третий вопрос с ходу:
Страуструп писал что при включенном RTTI — инфа ДОЛЖНА вставляться в каждый полиморфный класс.
Дальше — при выключенном RTSP VC6 на typeinfo показывает
offset XX * `RTTI Type Descriptor' (00427c58)
а по адресу идет что-то подозрительно похожее на сигнатуру 28 50 42 00
потом 4 нуля и какие-то данные
а хранит оно пойнтер на RTTI видимо общую таблицу последней записью в vtable.А там берется пойнтер на реальную RTTI запись.
Видимо RTTI инфа включаеться всегда (в случае использования) а ключ — просто для предупреждения ИМХО.
Кто знает точно — отзовитесь.
D>Попробую сформулировать вопросы.
D>При восходящем приведении (от производного к базовому) все в порядке.
D>D> X *x = dynamic_cast<X*>(xx);
D>
D>И если посмотреть в дизассемблере, то собственно RTTI для такого
D>приведения не требуется. Переменной 'x' тупо присваивается значение
D>переменной 'xx'
D>А вот при нисходящем уже требуется RTTI, и компилятор предупреждает
D>что в этой строке
D>D> XX *xx1 = dynamic_cast<XX*>(x); // ???
D>
D>используется dynamic_cast с полиморфичным классом при отключенной
D>опции /GR-. Включаем эту /GR и все в порядке. В MSDN написано что
D>эта опция позволяет компилятору добавлять код для проверки типа
D>объекта в рантайме.
D>И собственно вопросы:
D>1. Почему нормально работает оператор 'typeid' даже при отключенной
D> опции GR, что для 'typeid' не требуется RTTI
D>D> const type_info &tiXX = typeid(xx);
D> const type_info &tiX = typeid(x);
D>
D>2. Где живет эта информация об RTTI. В таблице виртуальных ф-ий что-то
D> не увидел я указателя на RTTI. Хотя это вопрос реализации, но все же
D> интересно.
D>3. Добавляется ли эта RTTI ко всем полиморфным классам программы или
D> только к классам, которые используются в dynamic_cast
Здравствуйте Dima2, Вы писали:
Что то не пойму дизассемблерный код этой строки
XX *xx1 = dynamic_cast<XX*>(x);
в обоих случаях (с /GR и /GR-) вроде бы одинаковый и структуры `RTTI Type Descriptor' тоже, но в одном случае вылетает исключение в другом нет.
Здравствуйте Dima2, Вы писали:
D>Здравствуйте Dima2, Вы писали:
D>Что то не пойму дизассемблерный код этой строки
D>D> XX *xx1 = dynamic_cast<XX*>(x);
D>
D>в обоих случаях (с /GR и /GR-) вроде бы одинаковый и структуры `RTTI Type Descriptor' тоже, но в одном случае вылетает исключение в другом нет.
Так не пойдет, выкинули на вторую страницу