Динамическое определение типа



Механизм идентификации типа во время выполнения программы (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; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!