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



Двоичная композиция - часть 2


Этот класс просто использует фактические реализации QueryInterface, AddRef и Release.

Рассмотрим второй класс C++, который пытается использовать реализацию Car как двоичный композит:

class CarBoat : public IBoat { LONG m_cRef; Unknown *m_pUnkCar; CarBoat(void); virtual ~CarBoat(void); STDMETHODIMP QueryInterface(REFIID, void **); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); STDMETHODIMP GetMaxSpeed(long *pn); STDMETHODIMP Sink(void); };

Для эмуляции композиции разработчику пришлось бы создать подобъект Car, а деструктору — освободить указатель на подобъект:

CarBoat::CarBoat (void) : m_cRef(0) { HRESULT hr = CoCreateInstance(CLSID_Car, 0, CLSCTX_ALL, IID_IUnknown, (void**)&m_pUnkCar); assert(SUCCEEDED(hr)); }

CarBoat::~CarBoat(void) { if (m_pUnkCar) m_pUnkCar->Release(); }

Интересная проблема возникает в реализации QueryInterface:

STDMETHODIMP CarBoat::QueryInterface(REFIID riid, void **ppv) { if (riid == IID_IUnknown) *ppv = static_cast<IUnknown*>(this); else if (riid == IID_IVehicle) *ppv = static_cast<IVehicle*>(this); else if (riid == IID_IBoat) *ppv = static_cast<IBoat*>(this); else if (riid == IID_ICar) // forward request... // переадресовываем запрос... return m_pUnkCar->QueryInterface(riid, ppv); else return (*ppv = 0), E_NOINTERFACE; ((IUnknown*)*ppv)->AddRef(); return S_OK; }

Поскольку объект Car не имеет понятия о том, что он является частью идентификационной единицы (identity) другого объекта, то он будет причиной неуспеха любых запросов QueryInterface для IBoat. Это означает, что

QI(IBoat)->ICar

пройдет успешно, а запрос

QI(QI(IBoat)->ICar)->IBoat

потерпит неудачу, так как полученная QueryInterface будет несимметричной. Вдобавок запросы QueryInterface о IUnknown через интерфейсные указатели ICar и IBoat вернут различные значения, а это означает, что будет идентифицировано два различных объекта. Из подобных нарушений протокола IUnknown следует, что объекты CarBoat попросту не являются действительными объектами СОМ.




Содержание  Назад  Вперед