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

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

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

#include

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();

 cout << "\n\n";

 if(typeid(i) == typeid(j))

  cout << "Типы переменных i и j одинаковы.\n";

 if(typeid(i) != typeid(f))

  cout << "Типы переменных i и f неодинаковы.\n";

 return 0;

}

При выполнении этой программы получены такие результаты.

Тип переменной i: int

Тип переменной f: float

Тип переменной ob: class myclass

Типы переменных i и j одинаковы.

Типы переменных i и f неодинаковы.

Если оператор typeid применяется к указателю на полиморфный базовый класс (вспомните: полиморфный класс — это класс, который содержит хотя бы одну виртуальную функцию), он автоматически возвращает тип реального объекта, на который тот указывает: будь то объект базового класса или объект класса, выведенного из базового.

Следовательно, оператор typeid можно использовать для динамического определения типа объекта, адресуемого указателем на базовый класс. Применение этой возможности демонстрируется в следующей программе.

/* Пример применения оператора typeid к иерархии полиморфных классов.

*/

#include

#include

using namespace std;

class Base {

 virtual void f() {}; // делаем класс Base полиморфным

 // . . .

};

class Derived1: public Base {

 // . . .

};

class Derived2: public Base {

 // ...

};

int main()

{

Перейти на страницу:

Все книги серии Изучайте C++ с профессионалами

Похожие книги