Assume I have a class implementing two or more COM interfaces (exactly as here):
class CMyClass : public IInterface1, public IInterface2 {
};
QueryInterface() must return the same pointer for each request of the same interface (it needs an explicit upcast for proper pointer adjustment):
if( iid == __uuidof( IUnknown ) ) {
*ppv = static_cast<IInterface1*>( this );
//call Addref(), return S_OK
} else if( iid == __uuidof( IInterface1 ) ) {
*ppv = static_cast<IInterface1*>( this );
//call Addref(), return S_OK
} else if( iid == __uuidof( IInterface2 ) ) {
*ppv = static_cast<IInterface2*>( this );
//call Addref(), return S_OK
} else {
*ppv = 0;
return E_NOINTERFACE;
}
now there're two IUnknowns in the object - one is the base of IInterface1 and the other is the base of IInterface2. And they are in different subobjects.
Let's pretend I called QueryInterface() for IInterface2 - the pointer returned will be different from the pointer returned when I call QueryInterface() for IUnknown. So far so good. Then I can pass the retrieved IInterface2* into any function accepting IUnknown* and thanks to C++ implicit conversion the pointer will be accepted, but it will be not the same pointer that QueryInterface() for IUnknown* would retrieve. In fact if that function calls QueryInterface() for IUnknown immediately upon being called it will retrieve a different pointer.
Is this legal in terms of COM? How do I handle situations when I have a pointer to a multiply-inherited object and I allow an implicit upcast?