русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Класс Type_info


Дата добавления: 2015-06-12; просмотров: 525; Нарушение авторских прав


В классе Type_info есть минимальный объем информации для реализации операции ptr_cast(); его можно определить следующим образом:

class Type_info {

const char* n; // имя

const Type_info** b; // список базовых классов

public:

Type_info(const char* name, const Type_info* base[]);

const char* name() const;

Base_iterator bases(int direct=0) const;

int same(const Type_info* p) const;

int has_base(const Type_info*, int direct=0) const;

int can_cast(const Type_info* p) const;

static const Type_info info_obj;

virtual typeid get_info() const;

static typeid info();

};

Две последние функции должны быть определены в каждом производном от Type_info классе.

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

const char* Type_info::name() const

{

return n;

}

 

int Type_info::same(const Type_info* p) const

{

return this==p || strcmp(n,p->n)==0;

}

 

int Type_info::can_cast(const Type_info* p) const

{

return same(p) || p->has_base(this);

}

Доступ к информации о базовых классах обеспечивается функциями bases() и has_base(). Функция bases() возвращает итератор, который порождает указатели на базовые классы объектов Type_info, а с помощью функции has_base() можно определить является ли заданный класс базовым для другого класса. Эти функции имеют необязательный параметр direct, который показывает, следует ли рассматривать все базовые классы (direct=0), или только прямые базовые классы (direct=1). Наконец, как описано ниже, с помощью функций get_info() и info() можно получить динамическую информацию о типе для самого класса Type_info.



Здесь средство динамических запросов о типе сознательно реализуется с помощью совсем простых классов. Так можно избежать привязки к определенной библиотеке. Реализация в расчете на конкретную библиотеку может быть иной. Можно, как всегда, посоветовать пользователям избегать излишней зависимости от деталей реализации.

Функция has_base() ищет базовые классы с помощью имеющегося в Type_info списка базовых классов. Хранить информацию о том, является ли базовый класс частным или виртуальным, не нужно, поскольку все ошибки, связанные с ограничениями доступа или неоднозначностью, будут выявлены при трансляции.

class base_iterator {

short i;

short alloc;

const Type_info* b;

public:

const Type_info* operator() ();

void reset() { i = 0; }

base_iterator(const Type_info* bb, int direct=0);

~base_iterator() { if (alloc) delete[] (Type_info*)b; }

};

В следующем примере используется необязательный параметр для указания, следует ли рассматривать все базовые классы (direct==0) или только прямые базовые классы (direct==1).

base_iterator::base_iterator(const Type_info* bb, int direct)

{

i = 0;

if (direct) { // использование списка прямых базовых классов

b = bb;

alloc = 0;

return;

}

// создание списка прямых базовых классов:

// int n = число базовых

b = new const Type_info*[n+1];

// занести базовые классы в b

alloc = 1;

return;

}

 

const Type_info* base_iterator::operator() ()

{

const Type_info* p = &b[i];

if (p) i++;

return p;

}

Теперь можно задать операции запросов о типе с помощью макроопределений:

#define static_type_info(T) T::info()

#define ptr_type_info(p) ((p)->get_info())

#define ref_type_info(r) ((r).get_info())

#define ptr_cast(T,p) \

(T::info()->can_cast((p)->get_info()) ? (T*)(p) : 0)

#define ref_cast(T,r) \

(T::info()->can_cast((r).get_info()) \

? 0 : throw Bad_cast(T::info()->name()), (T&)(r))

Предполагается, что тип особой ситуации Bad_cast (Ошибка_приведения) описан так:

class Bad_cast {

const char* tn;

// ...

public:

Bad_cast(const char* p) : tn(p) { }

const char* cast_to() { return tn; }

// ...

};

В разделе $$4.7 было сказано, что появление макроопределений служит сигналом возникших проблем. Здесь проблема в том, что только транслятор имеет непосредственный доступ к литеральным типам, а макроопределения скрывают специфику реализации. По сути для хранения информации для динамических запросов о типах предназначена таблица виртуальных функций. Если реализация непосредственно поддерживает динамическую идентификацию типа, то рассматриваемые операции можно реализовать более естественно, эффективно и элегантно. В частности, очень просто реализовать функцию ptr_cast(), которая преобразует указатель на виртуальный базовый класс в указатель на его производные классы.



<== предыдущая лекция | следующая лекция ==>
Информация о типе | Как создать систему динамических запросов о типе


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.142 сек.