Suppose I have a class implementing several interfaces
class CMyClass : public IInterface1, public IInterface2 { };
and in a member function of that class I need to obtain a void*
pointer to one of those interfaces (typical situation in IUnknown::QueryInterface()
.
The typical solution is to use a static_cast
to achieve pointer adjustment:
void* pointer = static_cast<IInterface2*>( this );
and it is safe in this case if there's no known class inherited from CMyClass
. But if such class exists:
class CDerivedClass : public CUnrelatedClass, public CMyClass {};
and I accidentially do
void* pointer = static_cast<CDerivedClass*>( this );
and this
is actually a pointer to CMyClass
instance the compiler won't catch me and the program might run into undefined behavior later - static_cast
becomes unsafe.
The suggested solution is to use implicit conversion:
IInterface2* interfacePointer = this;
void* pointer = interfacePointer;
Looks like this will solve both problems - pointer adjustment and risk of invalid downcast.
Are there any problems in the second solution? What could be the reasons to prefer the first one?
You could use this template:
template<class T, class U> T* up_cast(U* p) { return p; }
usage:
struct B {};
struct C : B {};
int main()
{
C c;
void* b = up_cast<B>(&c);
}
Note that the '*' is implicit. If you prefer up_cast<B*>
, adjust the template accordingly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With