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




Множественные интерфейсы и имена методов - часть 8


Поэтому правильной концовкой QueryInterface будет следующая:

((IUnknown*)(*ppv))->AddRef(); // use exact ptr // используем точный указатель return S_OK;

вместо такого:

AddRef(); // just call this->AddRef // только вызов this->AddRef return S_OK;

Первый вариант гарантирует, что если клиент пишет следующий правильный код

IBoat *pBoat = 0; HRESULT hr = pUnk->QueryInterface(IID_IBoat, (void**)&pBoat); if (SUCCEEDED(hr)) { hr = pBoat->Sink(); pBoat->Release(); }

то для AddRef и для Release обязательно будет использовано одно и то же значение указателя.

Можно осуществлять композицию в контексте управляемой таблицами реализации QueryInterface. При наличии семейства макросов препроцессора, показанного в предыдущей главе, достаточно всего одного дополнительного макроса, чтобы определить, что вместо базового класса используется элемент данных, и второго макроса, чтобы реализовать методы IUnknown в композите:

class CarBoatPlane : public ICar, public IPlane { public: struct XBoat : public IBoat { // composite QI/AddRef/Release/This() // композит из QI/AddRef/Release/This() IMPLEMENT_COMPOSITE_UNKNOWN(CarBoatPlane, XBoat, m_xBoat) STDMETHODIMP GetMaxSpeed(long *pval); STDMETHODIMP Sink(void); };

XBoat m_xBoat;

// IVehicle methods // методы IVehicle STDMETHODIMP GetMaxSpeed(long *pMax);

// ICar methods // методы ICar STDMETHODIMP Brake(void);

// IPlane methods // методы IPlane STDMETHODIMP TakeOff(void);

// standard heap-based QI/AddRef/Release // стандартные расположенные в "куче" QI/AddRef/Release

IMPLEMENT_UNKNOWN(CarBoatPlane) BEGIN_INTERFACE_TABLE(CarBoatPlane) IMPLEMENTS_INTERFACE_AS(IVehicle, ICar) IMPLEMENTS_INTERFACE(ICar) IMPLEMENTS_INTERFACE(IPlane) // macro that calculates offset of data member // макрос, вычисляющий смещение элемента данных IMPLEMENTS_INTERFACE_WITH_COMPOSITE(IBoat, XBoat, m_xBoat) END_INTERFACE_TABLE() };

В приведенном выше определении класса опущены только определения методов объекта вне QueryInterfасе, AddRef и Release.


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