When implementing IUnknown::QueryInterface()
in C++ there're several caveats with pointers manipulation. For example, when the class implements several interfaces (multiple inheritance) explicit upcasts are necessary:
class CMyClass : public IInterface1, public IInterface2 {
};
//inside CMyClass::QueryInterface():
if( iid == __uuidof( IUnknown ) ) {
*ppv = static_cast<IInterface1*>( this ); // upcast in order to properly adjust the pointer
//call Addref(), return S_OK
}
The reason for upcast is quite clear in multiple inheritance scenarios. However every here and there I also see the following:
static_cast<IUnknown*>( *ppv )->AddRef();
instead of simply invoking AddRef()
from inside QueryInterface()
implementation.
Is there any reason I should do the cast of the value previously copied into ppv
instead of just calling AddRef()
on the current object?
AddRef
is pure virtual in IUnknown
, and none of the other interfaces implement it, so the only implementation in your program is the one you write in CMyClass
. That one method overrides both IInterface1::AddRef
and IInterface2::AddRef
. IUnknown
doesn't have any data members (such as a reference count), so the diamond problem doesn't cause your class to be susceptible to a problem such as different calls to AddRef
acting on different data in the same class.
Calls to this->AddRef()
are going to be routed to the same place as static_cast<IUnknown*>(*ppv)->AddRef()
. I see no reason for the more verbose style.