# Rules for Implementing QueryInterface

There are three main rules than govern implementing the IUnknown::QueryInterface method on a COM object:

- Objects must have identity

- The set of interfaces on an object must be static

- It must be possible to query successfully for any interface on an object from any other interface

Objects must have identity. For any given object instance, a call to QueryInterface must always return the same physical pointer value. This allows you to call QueryInterface(IID_IUnknown, ...) on any two interfaces and compare the results to determine whether they point to the same instance of an object.

The set of interfaces on an object must be static. The set of interfaces accessible on an object via QueryInterface must be static, not dynamic. Specifically, if QueryInterface returns S_OK for a given IID once, it must never return E_NOINTERFACE on subsequent calls on the same object, and if QueryInterface returns E_NOINTERFACE for a given IID, subsequent calls for the same IID on the same object must never return S_OK.

It must be possible to query successfully for any interface on an object from any other interface. That is, given the following code:

    IA * pA = (some function returning an IA *);
    IB * pB = NULL;
    HRESULT   hr;
    hr = pA->QueryInterface(IID_IB, &pB); // line 4

the following rules apply:

- If you have a pointer to an interface on an object, a call like the following to QueryInterface for that same interface must succeed:

    pA->QueryInterface(IID_IA, ...)

- If a call to QueryInterface for a second interface pointer succeeds, a call to QueryInterface from that pointer for the first interface must also succeed. If in line 4 of the example, pB was successfully obtained, the following must also succeed:

    pB->QueryInterface(IID_IA, ...)

- Any interface must be able to query for any other interface on an object. So in line 4 of the example, pB was successfully obtained, and you successfully query for a third interface (IC) using that pointer, you must also be able to query successfully for IC using the first pointer, pA. In this case, the following sequence must succeed:

    IC * pC = NULL;
    hr = pB->QueryInterface(IID_IC, &pC);      //Line 7
    pA->QueryInterface(IID_IC, ...)

Interface implementations must maintain a counter that is large enough to support 231-1 outstanding pointer references to all the interfaces on a given object. Therefore, you should use a 32-bit unsigned integer for the counter.

If a client needs to know that resources have been freed, it must use a method in some interface on the object with higher-level semantics before calling Release.