Why do IUnknown* pointers retrieved through differ

2019-05-15 02:12发布

问题:

I have the following hierarchy of COM interfaces and a class implementing them:

interface IX : public IUnknown{};
interface IY : public IUnknown{};
class CA: public IX, public IY{};

Here class CA effectively inherits from IUnknown twice.

We know there are two vtable pointers in class CA - one is pointed to IX and another is pointed to IY. So IUnknown stored in the IX subobject is different from IUnknown stored in the IY subobject.

Yet when we call IX::QueryInterface() or IY::QueryInterface() on the same object and query IUnknown we get identical IUnknown* pointers.

Why does it happen?

回答1:

That's so called "object identity" requirement that states that whenever you request IUnknown from two objects you get distinct pointers if those are distinct objects and equal pointers if that's the same object.

Every QueryInterface() implementation must fulfill this requirement. This is usually done by choosing which one IUnknown to return and sticking to it:

HRESULT CA::QueryInterface( REFIID iid, void** ppv )
{
    if( iid == __uuidof( IUnknown ) ) {
        // Explicitly cast to one of base class subobjects.
        // Doesn't matter which one is chosen - it just has to be
        // the same base class subobject each time IUnknown is requested.
       IUnknown* selected = static_cast<IX*>( this );
       *ppv = selected;
       AddRef();
       return S_OK;
    } else {
       continue for other interfaces
    }
}