Выбрать главу

Глава 19: Динамическая идентификация типов и операторы приведения типа

В этой главе рассматриваются два средства C++, которые поддерживают современное объектно-ориентированное программирование: динамическая идентификация типов (run-time type identification - RTTI) и набор дополнительных операторов приведения типа. Ни одно из этих средств не было частью оригинальной спецификации C++, но оба они были добавлены с целью усиления поддержки полиморфизма времени выполнения. Под RTTI понимается возможность проведения идентификации типа объекта во время выполнения программы. Рассматриваемые здесь операторы приведения типа предлагают программисту более безопасные способы выполнения этой операции. Как будет показано ниже, один из них, dynamic_cast, непосредственно связан с RTTI-идентификацией, поэтому операторы приведения типа и RTTI имеет смысл рассматривать в одной главе.

Динамическая идентификация типов (RTTI)

С динамической идентификацией типов вы, возможно, незнакомы, поскольку это средство отсутствует в таких неполиморфных языках, как С. В неполиморфных языках попросту нет необходимости в получении информации о типе во время выполнения программы, так как тип каждого объекта известен во время компиляции (т.е. еще при написании программы). Но в таких полиморфных языках, как C++, возможны ситуации, в которых тип объекта неизвестен в период компиляции, поскольку точная природа этого объекта не будет определена до тех пор, пока программа на начнет выполняться. Как вы знаете, C++ реализует полиморфизм посредством использования иерархии классов, виртуальных функций и указателей на базовые классы. Указатель на базовый класс можно использовать для ссылки на члены как этого базового класса, так и на члены любого объекта, выведенного из него. Следовательно, не всегда заранее известно, на объект какого типа будет ссылаться указатель на базовый класс в произвольный момент времени. Это выяснится только при выполнении программы — при использовании одного из средств динамической идентификации типов.

Для получения типа объекта во время выполнения программы используйте оператор typeid.

Чтобы получить тип объекта во время выполнения программы, используйте оператор typeid. Для этого необходимо включить в программу заголовок <typeinfo>. Самый распространенный формат использования оператора typeid таков.

typeid(object)

Здесь элемент object означает объект, тип которого нужно получить. Можно запрашивать не только встроенный тип, но и тип класса, созданного программистом. Оператор typeid возвращает ссылку на объект типа type_infо, который описывает тип объекта object.

В классе type_info определены следующие public-члены.

bool operator = (const type_info &ob);

bool operator !=(const type_info &ob);

bool before(const type_info &ob);

const char *name();

Перегруженные операторы "==" и "!=" служат для сравнения типов. Функция before() возвращает значение true, если вызывающий объект в порядке сопоставления стоит перед объектом (элементом ob), используемым в качестве параметра. (Эта функция предназначена в основном для внутреннего использования. Возвращаемое ею значение результата не имеет ничего общего с наследованием или иерархией классов.) Функция name() возвращает указатель на имя типа.

Рассмотрим простой пример использования оператора typeid.

// Пример использования оператора typeid.

#include <iostream>

#include <typeinfo>

using namespace std;

class myclass {

 // . . .

};

int main()

{

 int i, j;

 float f;

 myclass ob;

 cout << "Тип переменной i: " << typeid(i).name();

 cout << endl;

 cout << "Тип переменной f: " << typeid(f).name();

 cout << endl;

 cout << "Тип переменной ob: " << typeid(ob).name();