Сущность технологии СОМ. Библиотека программиста | страница 128
void AssertSameObject(IUnknown *pUnk)
{
IUnknown *pUnk1 = 0,
*pUnk2 = 0;
HRESULT hr1 = pUnk->QueryInterface(IID_IUnknown, (void **)&pUnk1);
HRESULT hr2 = pUnk->QueryInterface(IID_IUnknown, (void **)&pUnk2);
// QueryInterface(IUnknown) must always succeed
// QueryInterface(IUnknown) должно всегда быть успешным
assert(SUCCEEDED(hr1) && SUCCEEDED(hr2));
// two requests for IUnknown must always yield the
// same pointer values
// два запроса на IUnknown должны всегда выдавать
// те же самые значения указателя
assert(pUnk1 == pUnk2);
pUnk1->Release();
pUnk2->Release();
}
Это требование позволяет клиентам сравнивать два любых указателя интерфейса для выяснения того, действительно ли они указывают на один и тот же объект.
bool IsSameObject(IUnknown *pUnk1, IUnknown *pUnk2)
{ assert(pUnk1 && pUnk2);
bool bResult = true;
if (pUnk1 != pUnk2)
{
HRESULT hr1, hr2; IUnknown *p1 = 0, *p2 = 0;
hr1 = pUnk1->QueryInterface(IID_IUnknown, (void **)&p1);
assert(SUCCEEDED(hr1));
hr2 = pUnk2->QueryInterface(IID_IUnknown, (void **)&p2);
assert(SUCCEEDED(hr2));
// compare the two pointer values, as these
// represent the identity of the object
// сравниваем значения двух указателей,
// так как они идентифицируют объект
bResult = (р1 == р2); p1->Release();
p2->Release();
}
return bResult;
}
В главе 5 будет рассмотрено, что понятие идентификации является фундаментальным принципом, так как он используется в архитектуре удаленного доступа СОМ с целью эффективно представлять интерфейсные указатели на объекты в сети.
Вооружившись знанием правил IUnknown, полезно исследовать реализацию объекта и убедиться в том, что она придерживается всех этих правил. Следующая реализация выставляет каждый из четырех интерфейсов средств транспорта и IUnknown:
class CarBoatPlane : public ICar, public IBoat, public IPlane
{
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);
// IBoat methods – методы