Динамическое определение типа
Механизм идентификации типа во время выполнения программы (RTTI) позволяет определять, на какой тип в текущий момент времени ссылается указатель, а также сравнивать типы объектов. Для доступа к RTTI в стандарт языка введена операция typeid и класс type_info. Формат операции typeid:
typeid (тип) typeid (выражение)
Операция принимает в качестве параметра имя типа или выражение и возвращает ссылку на объект класса type_info, содержащий информацию о типе. Если операция не может определить тип операнда, порождается исключение bad_typeid. Когда операнд представляет собой указатель или ссылку на полиморфный тип, результатом является динамическая информации о типе (то есть объект type_info содержит информацию о типе объекта, на который в данный момент ссылается указатель). Если операндом является выражение, представляющее собой ссылку на неполиморфный тип, объект type_info содержит информацию о типе выражения, а не о типе объекта, на который оно ссылается. Операцию typeid можно использовать как с основными, так и с производными типами данных. Класс type_info описан в заголовочном файле <typeinfo> следующим образом:
class type_info
{
public:
virtual ~type_info();
bool operator==(const type_info& rhs) const;
bool operator!=(const type_info& rhs) const;
bool before(const type_info& rhs) const;
const char* name() const;
private:
type_info(const type_info& rhs);
type_info& operator=(const type_info& rhs);
};
Метод name возвращает указатель на строку, представляющую имя типа, описываемого объектом типа type_info. Виртуальный деструктор делает класс type_info полиморфным. Конструктор копирования и операция присваивания объявлены как private, чтобы исключить возможность случайного копирования и присваивания объектов класса. Операции == и != позволяют сравнивать два объекта на равенство и неравенство, а функция before выполняет побуквенное сравнение имен двух типов. Для сравнения используется конструкция вида:
|
|
typeid(Tl).before(typeid(T2))
Если имя типа Т1 лексикографически предшествует имени Т2, результат будет истинным. Точная информация о типе объекта во время выполнения программы может потребоваться, например, когда программист расширяет функциональность некоторого библиотечного базового класса с помощью производного, и невозможно или бессмысленно добавлять к базовому классу виртуальные функции. Например:
#include <typeinfo.h>
class В
{
public: virtual ~В(){};
};
class С: public В
{
public: virtual void some_method(){ ... };
}
void demo(B* р)
{
if (typeid(*p) == typeid(C))
dynamic_cast<C*>(p)->some_method();
}
int main()
{
C* с = new C;
demo(c);
return 0;
}
Информацию о типе полезно использовать и в диагностических целях:
void print_type(some_obj *р)
{
cout « typeid(*p).name();
}
Операция typeid не должна применяться вместо виртуальных функций и в случаях, когда тип объекта можно определить на этапе компиляции.
Дата добавления: 2019-09-13; просмотров: 183; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!