Base *p, baseob;
Derived1 ob1;
Derived2 ob2;
p = &baseob
cout << "Переменная p указывает на объект типа ";
cout << typeid(*p).name() << endl;
p = &ob1
cout << "Переменная p указывает на объект типа ";
cout << typeid(*p).name() << endl;
p = &ob2
cout << "Переменная p указывает на объект типа ";
cout << typeid(*p).name() << endl;
return 0;
}
Вот как выглядят результаты выполнения этой программы:
Переменная р указывает на объект типа Base
Переменная р указывает на объект типа Derived1
Переменная р указывает на объект типа Derived2
Если оператор typeid
применяется к указателю на базовый класс полиморфного типа, тип реально адресуемого объекта, как подтверждают эти результаты, будет определен во время выполнения программы.Во всех случаях применения оператора typeid
к указателю на неполиморфную иерархию классов будет получен указатель на базовый тип, т.е. то, на что этот указатель реально указывает, определить нельзя. В качестве эксперимента превратите в комментарий виртуальную функцию f() в классе Base и посмотрите на результат. Вы увидите, что тип каждого объекта после внесения в программу этого изменения будет определен как Base, поскольку именно этот тип имеет указатель p.Поскольку оператор typeid
обычно применяется к разыменованному указателю (т.е. к указателю, к которому уже применен оператор "*"), для обработки ситуации, когда этот разыменованный указатель оказывается нулевым, создано специальное исключение. В этом случае оператор typeid генерирует исключение типа bad_typeid.Ссылки на объекты иерархии полиморфных классов работают подобно указателям. Если оператор typeid
применяется к ссылке на полиморфный класс, он возвращает тип объекта, на который она реально ссылается, и это может быть объект не базового, а производного типа. Описанное средство чаще всего используется при передаче объектов функциям по ссылке. Например, в следующей программе функция WhatType() объявляет ссылочный параметр на объекты типа Base. Это значит, что функции WhatType() можно передавать ссылки на объекты типа Base или ссылки на объекты любых классов, производных от Base. Оператор typeid, примененный к такому параметру, возвратит реальный тип объекта, переданного функции.
/* Применение оператора typeid к ссылочному параметру.
*/
#include
#include
using namespace std;
class Base {
virtual void f() {}; // делаем класс Base полиморфным
// . . .
};
class Derived1: public Base {
// . . .
};
class Derived2: public Base {
// . . .
};
/* Демонстрируем применение оператора typeid к ссылочному параметру.
*/
void WhatType(Base &ob)
{
cout << "Параметр ob ссылается на объект типа ";
cout << typeid(ob).name() << endl;
}
int main()
{
int i;
Base baseob;
Derived1 obi;
Derived2 ob2;
WhatType(baseob);
WhatType(ob1);
WhatType(ob2);
return 0;
}
Эта программа генерирует такие результаты.
Параметр ob ссылается на объект типа Base
Параметр ob ссылается на объект типа Derived1
Параметр ob ссылается на объект типа Derived2
Существует еще одна версия применения оператора typeid
, которая в качестве аргумента принимает имя типа. Формат ее таков.
tуре id(имя_типа)
Например, следующая инструкция совершенно допустима.
cout << typeid(int).name();
Назначение этой версии оператора typeid
— получить объект типа type_info (который описывает заданный тип данных), чтобы его можно было использовать в инструкции сравнения типов.Пример RTTI-приложения