Читайте также:
|
|
RTTI обеспечивается двумя операциями: typeid и, упомянутой выше, dynamic_cast. Операция typeid используется для возвращения имени типа переменной (объекта), а dynamic_cast – для нисходящего приведения типа указателя базового типа к указателю на производный (см. выше). Программы, использующие RTTI, должны быть скомпилированы компиляторами, которые поддерживают эту возможность (в Borland C++ Builder это ключ -RT, и /GR в MS Visual C++).
Опрерация typeid() определена в заголовке <typeinfo.h> (или <typeinfo>), который введен в стандарте ANSI/ISO C++. Операция принимает имя типа или выражение как операнд и возвращает объект (const ссылку) класса type_info. Полиморфный класс type_info содержит члены для описания типа. Метод класса type_info.name() возвращает строковый литерал, который является именем типа тестируемого операнда. Операция имеет две формы:
typeid (выражение) и typeid (имя_типа).
Если операнд операции typeid является разыменованным указателем или ссылкой на полиморфный тип, то операция возвращает динамический тип объекта, получаемого по указателю или ссылке на него. Если операнд – неполиморфный, то typeid вернет объект, представдяемый статическим типом. Эту операцию можно применять как к основным типам, так и производным. Если операнд – разыменованный нулевой указатель, порождается исключение bad_typeid. Класс type_info содержит операции-функции operator== и operator!=, что позволяет сравнивать типы объектов.
Пример 14-4.
#include<iostream>
using namespace std;
template <class T> void demo(T t)
{ cout << "The type of the parameter is " << typeid(T).name() << endl; }
class Point
{
int x, y;
public:
Point(int m = 0, int n = 0): x(m), y(n) { }
};
int main()
{
int n;
double x;
Point p(1, 2);
demo(n);
demo(x);
demo(p);
return 0;
}
Программа выводит:
The type of the parameter is int
The type of the parameter is double
The type of the parameter is class Point
Ну, и приведем пример на использование операции dynamic_cast.
Операция dynamic_cast<T*>(ptr) применяется к указателям. Обычно используется для проверки: указывает ли, в действительности, указатель на базовый класс на объект производного.
Пример 14-5.
#include <iostream.h>
class Base
{
public:
virtual void print() const
{ cout << "Base.\n"; }
void outB() // не виртуальная функция
{ cout << "Out Base.\n"; }
};
class D1: public Base
{
public:
void print() const // виртуальная
{ cout << "D1.\n"; }
void outD1() // не виртуальная
{ cout << "Out D1.\n"; }
};
class D2: public Base
{
public:
void print() const // виртуальная
{ cout << "D2.\n"; }
void outD2() // не виртуальная
{ cout << "Out D2.\n"; }
};
int main()
{
D1 d1;
D2 d2;
const D1* p1;
const D2* p2;
Base* p[2] = {&d1, &d2};
for (int count = 0; count < 2; ++count)
{
if (p1 = dynamic_cast<const D1*>(p[count]))
{
p1 -> print(); // срабатывает, также, и без приведения типа
p1 -> outD1(); // не будет работать без приведения
}
else if (p2 = dynamic_cast<const D2*>(p[count]))
{
p2 -> print(); // работает и без приведения
p2 -> outD2(); // не работает без приведения
}
}
return 0;
}
Дата добавления: 2015-11-16; просмотров: 55 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Dynamic_cast <тип *> (выражение). | | | Конструкторы, деструктор и перегрузка опрации присваивания в производном классе. |