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


Управление ресурсами - часть 2


Разместив эти методы, все пользователи IExtensibleObject должны теперь придерживаться следующих двух соображений: 1) Когда указатель интерфейса дублируется, требуется вызов DuplicatePointer. 2) Когда указатель интерфейса более не используется, следует вызвать DestroyPointer.

Эти методы могут быть реализованы в каждом объекте: нужно просто фиксировать количество действующих указателей и уничтожать объект, когда невыполненных указателей не осталось:

class FastString : public IFastString, public IPersistentObject { int m_cPtrs; // count of outstanding ptrs // счетчик невыполненных указателей public: // initialize pointer count to zero // сбросить счетчик указателя в нуль FastString(const char *psz) : m_cPtrs(0) { } void DuplicatePointer(void) { // note duplication of pointer // отметить дублирование указателя ++m_cPtrs; } void DestroyPointer(void) { // destroy object when last pointer destroyed // уничтожить объект, когда уничтожен последний указатель if (--m_cPtrs == 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<IFastString*>(this); else if (strcmp(pszType, "IPersistentObject") == 0) pvResult = static_cast<IPersistentObject*>(this); else if (strcmp(pszType, "IExtensibleObject") == 0) pvResult = static_cast<IFastString*>(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; }




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