, QueryInterf , , , , . , . , , , . " " , " ", . " " , " ", . " " (from that point on) " , ". C++, , ( , , ).
, , , , , , , :
void AssertStaticType(IUnknown *pUnk, REFIID riid) { IUnknown *pUnk1 = 0, *pUnk2 = 0; HRESULT hr1 = pUnk->QueryInterface(riid, (void**)&pUnk1); HRESULT hr2 = pUnk->QueryInterface(riid, (void**)&pUnk2); // both requests for the same interface should // yield the same yes/no answer // // / assert(SUCCEEDED(hr1) == SUCCEEDED(hr2)); if (SUCCEEDED(hr1)) pUnk1->Release(); if (SUCCEEDED(hr2)) pUnk2->Release(); }
, :
, "barring catastrophic failure" ( ).
, " / " . , ICar, IBoat IPlane, - . , , " " " " . , , :
class : public ICar, public IPlane, public IBoat { enum TYPE { CAR, BOAT, PLANE, NONE }; TYPE m_type; CBP(void) : m_type(NONE) { } STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { if (md == IID_ICar) { // 1st QI Initializes type of object // QI if (m_type == NONE) m_type = CAR; // only satisfy request if this object is a car // , // car ( ) if (m_type == CAR) *ppv = static_cast<ICar*>(this); else return (*ppv = 0), E_NOINTERFACE; } else if (md == IID_IBoat) { // similar treatment for IBoat and IPlane // IBoat IPlane } };
, , , , , " / " . , , , QueryInterface , . " " (client-side proxies) QueryInterface - . , , QueryInterface .