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 IUnknown
s 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?