class BASE {
public:
virtual ~BASE() {}
void lamp() {
cout << "\nBASE CLASS";
}
};
class DERIVED : public BASE {
public:
void fun();
};
void DERIVED::fun() {
cout << "\nDERIVED CLASS!";
}
int main() {
BASE * pbase = new DERIVED; //BASE CLASS POINTER
void * vbase = pbase; //VOID POINTER TAKING BASE POINTER
DERIVED * pder; //DERIVED CLASS POINTER
//pder = static_cast<DERIVED *>(vbase); //THIS WORKS
pder = dynamic_cast<DERIVED *>(vbase); //THIS DOESN'T
pder->lamp();
pder->fun();
return 0;
}
Whenever I try to dynamically cast the void*
pointer to the derived class pointer, I get the following error:
cannot dynamic_cast 'vbase' (of type 'void*') to type 'class DERIVED*' (source is not a pointer to class)
I've searched StackOverflow and followed advice by implementing a virtual function in the base class to avoid the error. What am I doing wrong? Is this possible at all?
My overall intention is to cast ANY incoming Object type into a Derived class type using a void*
pointer. I hope you understand what I mean.
For example:
void dynamicCast(void * vptr)
{
BASE * pbase = new DERIVED;
DERIVED * pder;
pder = dynamic_cast<DERIVED *>(vbase);
}
I should be able to pass any type of pointer to the dynamicCast
function and it should be converted to the derived class pointer.
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
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