Навигация
Главная
Поиск
Форум
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
Реклама
Сейчас на сайте
Гостей: 7
На сайте нет зарегистрированных пользователей

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

База данных электронного документооборота на Delphi + бд Intebase
Метод конечных разностей для интерполяции/экстраполяции на Delphi
Моделирование интернет кафе на GPSS + Отчет

Управление ресурсами



Еще одна проблема поддержки нескольких интерфейсов из одного объекта становится яснее, если исследовать схему использования клиентом метода DynamicCast . Рассмотрим следующую клиентскую программу:
void f(void)
{
IFastString *pfs = 0;
IPersistentObject *ppo = 0;
pfs = CreateFastString(«Feed BOB»);
if (pfs) {
ppo = (IPersistentObject *) pfs->Dynami cCast(«IPersistentObject»);
if ( !ppo) pfs->Delete();
else { ppo->Save(«C:\\autoexec.bat»);
ppo->Delete(); }
}
}



Хотя вначале объект был связан через свой интерфейс IFastString , клиентский код вызывает метод Delete через интерфейс IPersistentObject . С использованием свойства C++ о множественном наследовании это вполне допустимо, так как все таблицы vtbl , порожденные классом IExtensibleObject , укажут на единственную реализацию метода Delete . Теперь, однако, пользователь должен хранить информацию о том, какие указатели связаны с какими объектами, и вызывать Delete только один раз на объект. В случае простого кода, приведенного выше, это не слишком тяжелое бремя. Для более сложных клиентских кодов управление этими связями становится делом весьма сложным и чреватым ошибками. Одним из способов упрощения задачи пользователя является возложение ответственности за управление жизненным циклом объекта на реализацию. Кроме того, разрешение клиенту явно удалять объект вскрывает еще одну деталь реализации: тот факт, что объект находится в динамически распределяемой памяти (в «куче», on the heap).
Простейшее решение этой проблемы – ввести в каждый объект счетчик ссылок, который увеличивается, когда указатель интерфейса дублируется, и уменьшается, когда указатель интерфейса уничтожается. Это предполагает изменение определения IExtensibleObject с
class IExtensibleObject
{
public:
virtual void *DynamicCast (const char* pszType) =0;
virtual void Delete(void) = 0;
};
на
class IExtensibleObject
{
public:
virtual void *DynamicCast(const char* pszType) = 0;
virtual void DuplicatePointer(void) = 0;
virtual void DestroyPointer(void) = 0;
};



Разместив эти методы, все пользователи IExtensibleObject должны теперь придерживаться следующих двух соображений:
1) Когда указатель интерфейса дублируется, требуется вызов DuplicatePointer .
2) Когда указатель интерфейса более не используется, следует вызвать DestroyPointer .
Эти методы могут быть реализованы в каждом объекте: нужно просто фиксировать количество действующих указателей и уничтожать объект, когда невыполненных указателей не осталось:
class FastString : public IFastString,
public IPersistentObject
{
int mcPtrs;
// count of outstanding ptrs
// счетчик невыполненных указателей
public:
// initialize pointer count to zero
// сбросить счетчик указателя в нуль
FastString(const char *psz) : mcPtrs(0) { }
void DuplicatePointer(void)
{
// note duplication of pointer
// отметить дублирование указателя
++mcPtrs;
}
void DestroyPointer(void)
{
// destroy object when last pointer destroyed
// уничтожить объект, когда уничтожен последний указатель
if (-mcPtrs == 0) delete this;
}
: : :
};



Этот совершенно стандартный код мог бы просто быть включен в базовый класс или в макрос С-препроцессора, чтобы его могли использовать все реализации.
Чтобы поддерживать эти методы, все программы, которые манипулируют или управляют указателями интерфейса, должны придерживаться двух простых правил DuplicatePointer/DestroyPointer . Для реализации FastString это означает модификацию двух функций. Функция CreateFastString берет начальный указатель, возвращаемый новым оператором C++, и копирует его в стек для возврата клиенту. Следовательно, необходим вызов DuplicatePointer :
IFastString* CreateFastString(const char *psz)
{
IFastString *pfsResult = new FastString(psz);
if (pfsResult) pfsResult->DuplicatePointer();
return pfsResult;
}
Реализация копирует указатель и в другом месте – в методе Dynamic_Cast:
void *FastString::Dynamic_Cast(const char *pszType)
{
void *pvResult = 0;
if (strcmp(pszType, «IFastString») == 0) pvResult = static_cast(this);
else if (strcmp(pszType, «IPersistentObject») == 0) pvResult = static_cast(this); 
else if (strcmp(pszType, «IExtensibleObject») == 0) pvResult = static_cast(this);
else return 0;
// request for unsupported interface
// запрос на неподдерживаемый интерфейс
// pvResult now contains a duplicated pointer, so
// we must call DuplicatePointer prior to returning
// теперь pvResult содержит скопированный указатель,
// поэтому нужно перед возвратом вызвать DuplicatePointer
((IExtensibleObject*)pvResult)->DuplicatePo1nter();
return pvResult;
}



С этими двумя усовершенствованиями соответствующий код пользователя становится значительно более однородным и прозрачным:
void f(void)
{
IFastString *pfs = 0;
IPersistentObject *ppo = 0;
pfs = CreateFastString(«Feed BOB»);
if (pts) {
рро = (IPersistentObject *) pfs->DynamicCast(«IPersistentObject»);
if (ppo) { ppo->Save(«C:\\autoexec.bat»);
ppo->DestroyPointer(); }
pfs->DestroyPointer(); }
}



Поскольку каждый указатель теперь трактуется как автономный объект с точки зрения времени жизни, клиенту можно не интересоваться тем, какой указатель соответствует какому объекту. Вместо этого клиент просто придерживается двух простых правил и предоставляет объектам самим управлять своим временем жизни. При желании способ вызова DuplicatePointer и DestroyPointer можно легко скрыть за интеллектуальным указателем (smart pointer) C++.
Использование этой схемы вычисления ссылок позволяет объекту весьма единообразно выставлять множественные интерфейсы. Возможность выставления нескольких интерфейсов из одного класса реализации позволяет типу данных участвовать в различных контекстах. Например, новая постоянная подсистема могла бы определить собственный интерфейс для управления автозагрузкой и автозаписью объектов на некоторый специализированный носитель. Класс FastString мог бы добавить поддержку этих возможностей простым наследованием от постоянного интерфейса этой подсистемы. Добавление этой поддержки никак не повлияет на уже установленные базы клиентов, которые, может быть, используют прежний постоянный интерфейс для записи и загрузки строки на диск. Механизм согласования интерфейсов на этапе выполнения может служить краеугольным камнем для построения динамической системы из компонентов, которые могут изменяться со временем.
Опубликовал Kest July 10 2009 20:37:04 · 0 Комментариев · 6024 Прочтений · Для печати

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


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



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

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

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

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

Пароль



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

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

Случайные загрузки
БД студентов
Пример создания W...
FatScrollbar
«Философия» прогр...
Visual Studio 200...
Учебник для продв...
Электронный магаз...
Конвертирование и...
DFileDeleter
Популярные загрузки
3D Октаэдр
3d Tank [Исходник...
Socoban
Профессиональное ...
C++ Стандартная б...
Программирование ...
AddPage [Исходник...
EditNew
EditButton
DateEdit

Топ загрузок
Приложение Клие... 100774
Delphi 7 Enterp... 97832
Converter AMR<-... 20268
GPSS World Stud... 17014
Borland C++Buil... 14191
Borland Delphi ... 10290
Turbo Pascal fo... 7373
Калькулятор [Ис... 5984
Visual Studio 2... 5207
Microsoft SQL S... 3661
Случайные статьи
Рекомендации по ор...
ПАРАМЕТРИЗАЦИЯ В П...
Занятие 4. Проекти...
Обработка исключит...
Способы фильтрации...
Кэш просмотра ката...
Протокол динамичес...
Интернет – магазин...
Оценка ущерба
Коллекция объектов...
Мой окончательный ...
11.2. Простая быст...
Блок ASSIGN
пользователям
Использование клас...
( windowsupdate
ROX casino
Маршрутизаторы
Cобытийное моделир...
Создание процесса ...
Вращение вправо-вл...
Создание и редакти...
Создание приложения
14.7. Дополнительн...
Текст созданного S...
Статистика



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


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