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.
When you convert a pointer to an object type into a pointer to void, the only valid conversion for that void pointer is back to its original type . You can't use dynamic_cast
on a pointer to void
because void
is not a polymorphic type, so you do it with a static_cast
. Like this:
BASE *pbase = new DERIVED;
void *vbase = pbase; // Ok; implicit conversion to void*
BASE *pbase1 = static_cast<BASE*>(vbase); // the cast is required
Once you've gotten back the pointer to BASE
, of course, you can use dynamic_cast
to convert it to a pointer to the derived type:
DERIVED *pder = dynamic_cast<DERIVED*>(pbase1);
You cannot use dynamic_cast
on a void *
.
From the specification, for dynamic_cast<T>(v)
:
If T is a pointer type, v shall be a prvalue of a pointer to complete class type , and the result is a prvalue of type T. ...
What you should do is to let all your classes derive from the same polymorphic base class (which has at least one virtual function) BASE
, and use BASE *
instead of void *
.
Your generic linked list should be like this:
class Node
{
Node* next;
void* vdata;
}
That's the only data structure strictly required, but you might want a circular list, or a base node to keep track of the end of the list, or a doubly-linked list.
Caller passes you a void*, you create a new node, set "vdata" and add the node to your list.
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.