Сущность технологии COM


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


Еще одна проблема поддержки нескольких интерфейсов из одного объекта становится яснее, если исследовать схему использования клиентом метода Dynamic_Cast. Рассмотрим следующую клиентскую программу:

void f(void) { IFastString *pfs = 0; IPersistentObject *ppo = 0;

pfs = CreateFastString("Feed BOB"); if (pfs) { ppo = (IPersistentObject *) pfs->Dynamic_Cast("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 *Dynamic_Cast (const char* pszType) =0; virtual void Delete(void) = 0; };

на

class IExtensibleObject { public: virtual void *Dynamic_Cast(const char* pszType) = 0; virtual void DuplicatePointer(void) = 0; virtual void DestroyPointer(void) = 0; };




Начало  Назад  Вперед