Andrew
Andrew

Reputation: 24846

c++ casting derived to void* and restoring base

I have:

class A {...};

class B : public A {...};

class C : public B {...};

Then I'm storing C instance as void*:

C *instance = new C();
void *pC = instance;

Is it ok to make this:

B *pB = reinterpret_cast<B*>(pC);

Or I have to cast to C* only?

PS: I have more classes derived from B in my program and I'm not sure if's ok to cast like i'm doing (to B*).

Why void*: I'm using void *userdata' field of physical body class in box2d engine. I can't store my class there in other way

Upvotes: 2

Views: 400

Answers (5)

Konstantin Oznobihin
Konstantin Oznobihin

Reputation: 5327

For the code you shown it should be ok to cast directly to B* and you can use static_cast for this. However, in general, pointers to base and derived classes might be different and you'll have to cast to the original type first and only then cast it to the pointer to base.

Edit: that should be ok in practice for single inheritance, but in general it's UB.

Upvotes: 1

CashCow
CashCow

Reputation: 31445

The general rule is that when you cast from a pointer to void * you should always cast back to the one you originally came from.

Casting to void* is sometimes a necessary evil because of old APIs.

And sometimes it is done by design to create a "light" template. A light template is where you write code that handles a collection of pointers to objects, which are all handled in the same way, and this prevents code having to be generated for every type.

Around this code you have a strongly typed template that does the simple thing of casting back and forth (likely to be inlined anyway) so the users get strongly typed code but the implementation is less bloated.

Upvotes: 1

vishakvkt
vishakvkt

Reputation: 864

Casting to void* is always a bad idea and so is doing a dynamic_cast. If you have to, it mostly means your code requires re-factoring as it is an object design flaw.

Upvotes: -1

Sebastian Krysmanski
Sebastian Krysmanski

Reputation: 8394

This will work fine. You'll only get access to methods of A and B in this case though. (You'll simply "hide" methods of C.)

Upvotes: 0

AndersK
AndersK

Reputation: 36082

I would suggest casting it back to the original C* then do a dynamic_cast to B* in order to follow the rules of C++ - although you should avoid casting to void* in the first place and instead use a base pointer (A*) instead of void ptr.

Upvotes: 3

Related Questions