Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any reason to prefer static_cast over a chain of implicit conversions?

Tags:

c++

casting

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?

like image 252
sharptooth Avatar asked Jan 20 '23 13:01

sharptooth


1 Answers

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.

like image 184
Sjoerd Avatar answered Feb 19 '23 11:02

Sjoerd