Dynamic_Cast from "Void *"

dynamic_cast from void *

dynamic_cast works only on polymorphic types, i.e. classes containing virtual functions.

In gcc you can dynamic_cast to void* but not from:

struct S
{
virtual ~S() {}
};

int main()
{
S* p = new S();
void* v = dynamic_cast<void*>(p);
S* p1 = dynamic_cast<S*>(v); // gives an error
}

How do I dynamically cast from a void * pointer generically?

I think there is a design or/and comprehension problem

As explained you can not dynamic_cast from a void*.

Why? Because dynamic_cast needs some Run-Time Type Information (RTTI) to do the cast (see this link for further details). From void* alone, the C++ code has no chance to know where this information is. The minimum is to use a pointer to an object having such RTTI information.

This information is created and bounded to any class having at least one virtual method. If there is no virtual method this information is not included. That is the reason why this does not work:

struct A
{
};

struct B : A
{
};

int main()
{
B b;
A *a = &b;

dynamic_cast<B *>(a); // YOUR COMPILE TIME ERROR
}

A fix is to add a virtual method to A. Here I have added a virtual destructor as this is generally a good thing

struct A
{
virtual ~A() = default;
};

struct B : A
{
};

int main()
{
B b;
A *a = &b;

dynamic_cast<B *>(a); // OK
}

Also note that dynamic_cast allows you to check that the conversion was legal.

For instance we can add a C class and check:

struct C 
{
};

int main()
{
B b;
A *a = &b;

assert(dynamic_cast<B *>(a)!=nullptr); // OK
assert(dynamic_cast<C *>(a)==nullptr); // OK can not cast A to C
}

This kind of run-time operations are not free. If you search for maximum speed to can use this trick:

assert(dynamic_cast<B *>(a)!=nullptr);
B* b=static_cast<B*>(a);

In debug mode you will check if everything is ok and in release mode with the -DNDEBUG flag to remove the assert you will only use the static_cast

Why would I use dynamic_cast to cast TO a void *?

First, when using dynamic_cast<void*>(x) you get a pointer to the first byte of the most derived object. As long as the static type of x is polymorphic.

This can be useful in a handful of scenarios, where the address serves as object identity:

  • you now have a way to fully distinguish pointers to subobjects of the same object from pointers to unrelated subobjects.
  • you can now walk some twisted graphs without visiting the same object several times... which can be used for serialization.

Granted, this is certainly not a daily usage, but in C++ the memory address is a de-facto identifier for objects, so a mechanism to access it from any part of the inheritance hierarchy certainly is useful for those few edge cases.

Safe way to dynamic cast void to a type?

The only thing you can do with a void* pointer is to cast it back to exactly the same type as the pointer that was cast to void* in the first place. The behaviour on doing anything else is undefined.

What you could do in your case is define

class Base
{
public:
virtual ~Base() = default; // make me a polymorphic type and make
// polymorphic delete safe at the same time.
};

and make this the base class for Alpha and Beta. Then pass a Base* pointer around rather than a void* one, and take your dynamic_casts directly on p.

Note further that if you declared virtual void Speak() = 0; in Base, then your code in main would become simply

int main(){ 
Base* p = new Alpha;
p->Speak();
delete p; // ToDo - have a look at std::unique_ptr
}

As a rule of thumb, casts of any kind are undesirable.

Cannot dynamic_cast void* to templated class

Dynamic cast requires polymorphic behavior, which void does not have. Use a static_cast instead.

When is dynamic_castvoid* useful?

One common reason is to figure out whether two interfaces IA* and IB* are in fact pointers to the same underlying object. If you need that, use the cast.

IIRC, it's even possible in case of Multiple Inheritance with a repeated non-virtual base to have two IA* pointers which compare unequal, yet point to the same object - because they point to two different IA subobjects.

Exception thrown when trying to access a protected variable from a child class after a dynamic casting

dynamic_cast will never lie. It checks the runtime type of the object to see if it matches the T gi8ven in the dynamic_cast<T>. You created an instance of the Entity base class. The runtime type of this object is Entity because that's what you created.

dynamic_cast knows the runtime type of the object, so it knows dynamic_cast<Player*> cannot work since the object isn't a Player object. Therefore, it returns nullptr.

static_cast doesn't know if the object is a Player or not; it assumes that it is and returns a pointer to that object if it is there. But since it's not there, any attempt to use the result of the static_cast yields undefined behavior.

Which just so happens to do what you want, but there's no guarantee of that.

dynamic cast from father to child

dynamic_cast generally requires polymorphic types. That means the types involved must have at least one virtual member function (can be a destructor).



Related Topics



Leave a reply



Submit