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


Реализация IUnknown - часть 3


Для простой реализации это весьма разумно, так как СОМ не допускает более одного потока для обращения к объекту до тех пор, пока конструктор не обеспечит явный многопоточный доступ (почему и как конструктор сделает это, подробно описано в главе 5). В случае объектов, доступных в многопоточной среде, для автоматического подсчета ссылок следует использовать подпрограммы Win32 InterlockedIncrement/InterlockedDecrement:

STDMETHODIMP_(ULONG) AddRef(void) { return InterlockedIncrement(&m_cRef); }

STDMETHODIMP_(ULONG) Release(void) { LONG res = InterlockedDecrement(&m_cRef); if (res == 0) delete this; return res; }

Этот код несколько менее эффективен, чем версии, использующие собственные операторы C++. Но, вообще говоря, разумнее использовать менее эффективные варианты InterlockedIncrement / InterlockedDecrement, так как известно, что они надежны во всех ситуациях и освобождают разработчика от необходимости сохранять две версии практически одинакового кода.

Показанные выше реализации AddRef и Release предполагают, что объект может размещаться только в динамически распределяемой области памяти (в "куче") с использованием С++-оператора new. В определении класса деструктор сделан защищенной операцией для обеспечения того, чтобы ни один экземпляр класса не был определен никаким другим способом. Однако иногда желательно иметь объекты, не размещенные в «куче». Для этих объектов вызов delete в последнем вызове Release был бы гибельным. Так как единственной причиной для того, чтобы объект в первую очередь поддерживал счетчик ссылок, была необходимость вызова delete this, допустимо оптимизировать счетчик ссылок для объектов, не содержащихся в динамически распределяемой области памяти:

STDMETHODIMP_(ULONG) GlobalVar::AddRef(void) { return 2; // any non-zero value is legal // допустима любая ненулевая величина }

STDMETHODIMP_(ULONG) GlobalVar::Release (void) { return 1; // any non-zero value is legal // допустима любая ненулевая величина }

Эта реализация использует тот факт, что результаты AddRef и Release служат только для сведения и не обязаны быть точными.




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



Книжный магазин