Программирование >>  Инициализация объектов класса, структура 

1 ... 326 327 328 [ 329 ] 330 331 332 ... 395


#include <typeinfo> pobj ;

programmer pobj; employee Sre = pobj;

п б61ёбёаё name() 1fl 11д1аё11ё1пу а Иабадааёа, ИпауйаНИ type info / / на агдабайааб C-n6бlё6 programmer

сообщает тип производного класса объекта:

coiut << typeid( re ).name() << endl;

Операнд re оператора typeid имеет тип employee. Но так как re - это ссылка на тип класса с виртуальными функциями, то typeid говорит, что тип адресуемого объекта -programmer (а не employee, на который ссылается re). Программа, использующая такой оператор, должна включать заголовочный файл <typeinfo>, что мы и сделали в этом примере.

Где применяется typeid? В сложных системах разработки, например при построении отладчиков, а также при использовании устойчивых объектов, извлеченных из базы данных. В таких системах необходимо знать фактический тип объекта, которым программа манипулирует с помощью указателя или ссылки на базовый класс, например для получения списка его свойств во время сеанса работы с отладчиком или для правильного сохранения или извлечения объекта из базы данных. Оператор typeid допустимо использовать с выражениями и именами любых типов. Например, его операндами могут быть выражения встроенных типов и константы. Если операнд не

int iobj;

cout << typeid( iobj ).name() << endl; гаабаабйу: int

принадлежит к типу класса, то typeid просто возвращает его тип:

cout << typeid( 8.16 ).name() << endl; печатается: double

Если операнд имеет тип класса, в котором нет виртуальных функций, то typeid

class Base { /* нет виртуальн1х функций */ };

class Derived : public Base { /* 1аб аёб6баёй1йб б61ёбёё */ };

Derived dobj; Base *pb = Sdobj;

возвращает тип операнда, а не связанного с ним объекта:

cout << typeid( *pb ).name() << endl; печатается: Base

19.1.2. Оператор typeid

Второй оператор, входящий в состав RTTI, - это typeid, который позволяет выяснить фактический тип выражения. Если оно принадлежит типу класса и этот класс содержит хотя бы одну виртуальную функцию-член, то ответ может и не совпадать с типом самого выражения. Так, если выражение является ссылкой на базовый класс, то typeid



#include <typeinfo>

employee *pe = new m employees re = *pe;

manager;

employees re = *pe; if ( typeid( pe ) == typeid( employee* ) ) en6eiil +6l-6l naaea6u

if ( typeid( pe ) == typeid( manager* ) ) elail if ( typeid( pe ) == typeid( employee ) ) elail if ( typeid( pe ) == typeid( manager ) ) elail

Результаты, возвращенные оператором typeid, можно сравнивать. Например:

Условие в инструкции if сравнивает результаты применения typeid к операнду, являющемуся выражением, и к операнду, являющемуся именем типа. Обратите внимание, что сравнение

typeid( pe ) == typeid( employee* )

вызов виртуальной функции

возвращает истину. Это удивит пользователей, привыкших писать:

pe->salary();

что приводит к вызову виртуальной функции salary() из производного класса manager. Поведение typeid(pe) не подчиняется данному механизму. Это связано с тем, что pe -указатель, а для получения типа производного класса операндом typeid должен быть тип класса с виртуальными функциями. Выражение typeid(pe) возвращает тип pe, т.е. указатель на employee. Это значение совпадает со значением typeid(employee*) , тогда как все остальные сравнения дают ложь.

Только при употреблении выражения *pe в качестве операнда typeid результат будет

typeid( *pe ) == typeid( manager ) истинно

содержать тип объекта, на который указывает pe:

typeid( *pe ) == typeid( employee ) ложно

В этих сравнениях *pe - выражение типа класса, который имеет виртуальные функции, поэтому результатом применения typeid будет тип адресуемого операндом объекта manager.

Такой оператор можно использовать и со ссылками:

Операнд typeid имеет тин Base, т.е. тин выражения *pb. Поскольку в классе Base нет виртуальных функций, результатом typeid будет Base, хотя объект, на который указывает pb, имеет тин Derived.



class type info {

1баапбааёа1ёа дааёДёб 16 бааёёдабёё private:

type info( const type infoS ); type info& operator= ( const type info& );

public:

virtual ~type info();

int operator==( const type infoS ); int operator!=( const type infoS );

const char * name() const;

характерные черты остаются неизменными в любой программе на C++:

Поскольку копирующие конструктор и оператор присваивания - закрытые члены класса

#include <typeinfo>

type info t1; 10ёаёа: 1а6 ё11п6б6ё61ба И 611ёа1ё 10ёаёа: ё11ёб6йёё ё11п6б6ё61б 5аёбй6

type info, то пользователь не может создать его объекты в своей программе:

type info t2 (typeid( unsigned int ) );

Единственный способ создать объект класса type info - воспользоваться оператором typeid.

В классе определены также операторы сравнения. Они позволяют сравнивать два объекта type info, а следовательно, и результаты, возвращенные двумя операторами typeid. (Мы говорили об этом в предыдущем подразделе.)

typeid( re ) == typeid( manager ) истинно

typeid( re ) == typeid( employee ) ложно typeid( Sre ) == typeid( employee* ) истинно

typeid( Sre ) == typeid( manager* ) ложно

В первых двух сравнениях операнд re имеет тип класса с виртуальными функциями, поэтому результат применения typeid содержит тип объекта, на который ссылается re. В последних двух сравнениях операнд Sre имеет тип указателя, следовательно, результатом будет тип самого операнда, т. е. employee*.

На самом деле оператор typeid возвращает объект класса типа type info, который определен в заголовочном файле <typeinfo>. Интерфейс этого класса показывает, что можно делать с результатом, возвращенным typeid. (В следующем подразделе мы подробно рассмотрим этот интерфейс.)

19.1.3. Класс type info

Точное определение класса type info зависит от реализации, но некоторые его



1 ... 326 327 328 [ 329 ] 330 331 332 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика