Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 5
На сайте нет зарегистрированных пользователей

Пользователей: 13,372
новичок: vausoz
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Расчет мер близости на отношениях на Delphi + Пояснительная записка
База данных электронного документооборота на Delphi + бд Intebase
База данных студентов на Delphi (файл записей) + Блок схемы

Расширяемость объекта

Чтобы записать FastString на диск, пользователю достаточно с помощью RTTI связать указатель с интерфейсом IPerststentObject, который выставляется объектом:
bool SaveString(IFastString *pfs, const char *pszFN)
{
bool bResult = false;
IPersistentObject *ppo = dynamic_cast(pfs);
if (ppo) bResult = ppo->Save(pszFN);
return bResult;
}



Эта методика работает, поскольку транслятор имеет достаточно информации о представлении и иерархии типов класса реализации, чтобы динамически проверить объект для выяснения того, действительно ли он порожден от IPersistentObject. Но здесь есть одна проблема.
RTTI – особенность, сильно зависящая от транслятора. В свою очередь, DWP передает синтаксис и семантику RTTI, но каждая реализация RTTI разработчиком транслятора уникальна и запатентована. Это обстоятельство серьезно подрывает независимость от транслятора, которая была достигнута путем использования абстрактных базовых классов как интерфейсов. Это является неприемлемым для архитектуры компонентов, не зависимой от разработчиков. Удачным решением было бы упорядочение семантики dynamic_cast без использования свойств языка, зависящих от транслятора. Явное выставление хорошо известного метода из каждого интерфейса, представляющего семантический эквивалент dynamic_cast, позволяет достичь желаемого эффекта, не требуя, чтобы все объекты использовали тот же самый транслятор C++:
class IPersistentObject
{
public: virtual void *Dynamic_Cast(const char *pszType) = 0;
virtual void Delete(void) = 0;
virtual bool Load(const char *pszFileName) = 0;
virtual bool Save(const char *pszFileName) = 0;
};
class IFastString
{
public: virtual void *Dynamic_Cast(const char *pszType) = 0;
virtual void Delete(void) = 0;
virtual int Length(void) = 0;
virtual int Find(const char *psz) = 0;
};



Так как всем интерфейсам необходимо выставить этот метод вдобавок к уже имеющемуся методу Delete, имеет большой смысл включить общее подмножество методов в базовый интерфейс, из которого могли бы порождаться все последующие интерфейсы:
class IExtensibleObject { public: virtual void *Dynamic_Cast(const char* pszType) = 0; virtual void Delete(void) = 0; }; class IPersistentObject : public IExtensibleObject { public: virtual bool Load(const char *pszFileName) = 0; virtual bool Save(const char *pszFileName) = 0; }; class IFastString : public IExtensibleObject { public: virtual int Length(void) = 0; virtual int Find(const char *psz) = 0; };



Имея такую иерархию типов, пользователь может динамически запросить объект о данном интерфейсе с помощью следующей не зависящей от транслятора конструкции:
bool SaveString(IFastString *pfs, const char *pszFN) { boot bResult = false; IPersistentObject *ppo = (IPersistentObject) pfs->Dynamic_Cast(«IPers1stentObject»); if (ppo) bResult = ppo->Save(pszFN); return bResult; }



В только что приведенном примере клиентского использования присутствуют требуемая семантика и механизм для определения типа, но каждый класс реализации должен выполнять это функциональное назначение самолично:
class FastString : public IFastString, public IPersistentObject
{
int m_cсh;
// count of characters
// счетчик символов
char *m_psz;
public:
FastString(const char *psz);
~FastString(void);
// IExtensibleObject methods
// методы IExtensibleObject
void *Dynamic_Cast(const char *pszType);
void Delete(void);
// deletes this instance
// удаляет этот экземпляр
// IFastString methods
// методы IFastString
int Length(void) const;
// returns # of characters
// возвращает число символов
int Find(const char *psz) const;
// returns offset
// возвращает смещение
// IPersistentObject methods
// методы IPersistentObject
bool Load(const char *pszFileName);
bool Save(const char *pszFileName);
};



Реализации Dynamic_Cast необходимо имитировать действия RTTI путем управления иерархией типов объекта. Рисунок 1.8 иллюстрирует иерархию типов для только что показанного класса FastString. Поскольку класс реализации порождается из каждого интерфейса, который он выставляет, реализация Dynamic_Cast в FastString может просто использовать явные статические приведения типа (explicit static casts), чтобы ограничить область действия указателя this, основанного на подтипе, который запрашивается клиентом:
void *FastString::Dynam1c_Cast(const char *pszType)
{
if (strcmp(pszType, «IFastString») == 0) return static_cast(this);
else if (strcmp(pszType, «IPersistentObject») == 0) return static_cast(this);
else if (strcmp(pszType, «IExtensibleObject») == 0) return static_cast(this);
else return 0;
// request for unsupported interface
// запрос на неподдерживаемый интерфейс
}



Так как объект порождается от типа, используемого в этом преобразовании, оттранслированные версии операторов преобразования просто добавляют определенное смещение к указателю объекта this, чтобы найти начало представления базового класса.
Отметим, что после запроса на общий базовый интерфейс IExtensibleObject реализация статически преобразуется в IFastString. Это происходит потому, что интуитивная версия (intuitive version) оператора
return static_cast(this);



неоднозначна, так как и IFastString, и IPersistentObject порождены от IExtensibleObject. Если бы IExtensibleObject был виртуальным базовым классом как для IFastString, так и для IPersistentObject, то данное преобразование не было бы неоднозначным и оператор бы оттранслировался. Тем не менее, применение виртуальных базовых классов добавляет на этапе выполнения ненужную сложность в результирующий объект и к тому же вносит зависимость от транслятора. Дело в том, что виртуальные базовые классы являются всего лишь особенностями языка C++, которые имеют несколько специфических реализации.
Опубликовал Kest July 10 2009 20:35:36 · 0 Комментариев · 9801 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Страница 2 из 2 < 1 2
Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Turbo Pascal for ...
Ильдар Хабибуллин...
Распознавание иде...
Microsoft Press -...
ComboBox97
Современное проек...
CoolControls v3.0...
Усложнённый кальк...
В.Понамарев - COM...
Секреты программи...
DCMintry
WAP версия сайта
Применение жадног...
45 уроков по дельфи
AUTOWEB
Длинный заголовок...
Программирование ...
Отключение и вклю...
TrayComp
Degisy Data Acces...

Топ загрузок
Приложение Клие... 100774
Delphi 7 Enterp... 97838
Converter AMR<-... 20268
GPSS World Stud... 17014
Borland C++Buil... 14192
Borland Delphi ... 10292
Turbo Pascal fo... 7374
Калькулятор [Ис... 5984
Visual Studio 2... 5207
Microsoft SQL S... 3661
Случайные статьи
Безопастность Dial...
Разборка приставки...
Директивы компилятора
Точка USR 2450, De...
Файловая система t...
Выделение памяти я...
О стандартах прогр...
Конкретизация шабл...
Формат фотографии ...
АЙ СИК Ю? АЙ ХАК Ю!
Министерство нацио...
Протокол MNP
Задачи, решаемые н...
Нужно добавить доп...
Кэш просмотра ката...
• Administrators (...
отбор лучшего вари...
Секреты: принцип р...
Active Directory— ...
Стандарты коммуник...
• Computer Configu...
• Management — гло...
Используя такую те...
Goal,Rules. камеры...
2.2. Литеры
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?