views:

163

answers:

1

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?

+2  A: 

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.

Rob Kennedy