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


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


Отметим, что в классе должен быть реализован каждый метод, определенный в любом интерфейсе, от которого он наследует, так же, как и каждый метод, определенный в любых производных (implied) базовых интерфейсах (например, IDog, IAnimal). Для создания стековых фреймов, совместимых с СОМ, необходимо использовать макросы STDMETHODIMP и STDMETHODIMP_. При ориентации на платформы Win32, использующие компилятор Microsoft C++, заголовки SDK определяют эти два макроса следующим образом:

#define STDMETHODIMP HRESULT _stdcall #define STDMETHODIMP_(type) type _stdcall

Заголовочные файлы SDK также определяют макросы STDMETHOD и STDMETHOD_, которые можно использовать при определении интерфейсов без IDL-компилятора. В серийно выпускаемом программировании на СОМ эти два макроса не нужны.

Реализация AddRef и Release чрезвычайно прозрачна. Элемент данных m_cRef отслеживает, сколько неосвобожденных интерфейсных указателей удерживают объект. Конструктор класса приводит счетчик ссылок в нулевое состояние:

PugCat::PugCat(void) : m_cRef(0) // initialize reference count to zero // устанавливаем счетчик ссылок в нуль { }

Реализация AddRef в классе фиксирует путем увеличения счетчика ссылок, что вызывающий объект продублировал указатель интерфейса. Измененное значение счетчика ссылок возвращается для целей диагностики:

STDMETHODIMP_(ULONG) AddRef(void) { return ++m_cRef; }

Реализация Release фиксирует уничтожение указателя интерфейса простым уменьшением счетчика ссылок, а также производит соответствующее действие, когда счетчик ссылок достигает нуля. Для объектов, находящихся в динамически распределяемой области памяти, это означает вызов оператора delete для уничтожения объекта:

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

Для кэширования обновленного счетчика ссылок необходимо использовать временную переменную, так как нельзя обращаться к элементам данных объекта после того, как объект уже уничтожен.

Заметим, что показанные реализации Addref и Release используют собственные операторы инкремента и декремента (увеличения и уменьшения на единицу).


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



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