|
Программирование >> Инициализация объектов класса, структура
#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 зависит от реализации, но некоторые его
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |