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



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


Для отделяемого интерфейса должен быть определен второй класс, наследующий тому интерфейсу, который он будет реализовывать. Чтобы обеспечить идентификацию, QueryInterface отделяемого интерфейса должен делегировать управление функции QueryInterface основного класса. Два основных различия заключаются в том, что: 1) главный объект динамически размещает отделяемый интерфейс вместо того, чтобы иметь элемент данных экземпляра, и 2) отделяемый композит должен содержать явный обратный указатель на главный объект, так как технология фиксированного смещения, используемая в композиции, здесь не работает, поскольку отделяемый интерфейс изолирован от основного объекта. Следующий класс реализует IBoat как отделяемый интерфейс:

class CarBoat : public ICar { LONG m_cRef; CarBoat (void): m_cRef(0) {} public: // IUnknown methods // методы IUnknown STDMETHODIMP QueryInterface(REFIID, void**); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); // IVehicle methods // методы IVehicle STDMETHODIMP GetMaxSpeed(long *pMax); // ICar methods // методы ICar STDMETHODIMP Brake(void); // define nested class that implements IBoat // определяем вложенный класс, реализующий IBoat struct XBoat : public IBoat { LONG m_cBoatRef; // back pointer to main object is explicit member // обратный указатель на главный объект - явный член CarBoat *m_pThis; inline CarBoat* This() { return m_pThis; } XBoat(CarBoat *pThis); ~XBoat(void); STDMETHODIMP QueryInterface(REFIID, void**); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); STDMETHODIMP GetMaxSpeed(long *pval); STDMETHODIMP Sink(void); }; // note: no data member of type Xboat // заметим: нет элементов данных типа Xboat };

Для QueryInterface главного объекта необходимо динамически разместить новый отделяемый интерфейс — каждый раз, когда запрашивается IBoat:

STDMETHODIMP CarBoat::QueryInterface(REFIID riid, void **ppv) { if (riid == IID_IBoat) *ppv = static_cast<IBoat*>(new XBoat(this)); else if (riid == IID_IUnknown) *ppv = static_cast<IUnknown*>(this); : : :




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