Drop pointers prior to void* have their importance starting from C-days. The most suitable place is in the operating system's memory manager. It should store the entire pointer and object of what you are creating. By storing it in void *, they generalize it to store any object in the memory manager's data structure, which can be heap/B+Tree or a simple arraylist .
For simplicity, take an example of creating a list common elements (The list contains elements of completely different classes). This could only be used with void* .
standard says dynamic_cast should return null for odd type casting, and the standard also ensures that any pointer must be able to enter it into void * and back from it with the exception of only function pointers.
The practical use of the standard application layer is very small for void* typecasting, but it is widely used in low-level / embedded systems.
Usually you would like to use reinterpret_cast for low-level material, for example, in 8086 it is used to shift the pointer of the same base to get the address, but not limited to it.
Edit: The standard says that you can convert any pointer to void* even with dynamic_cast<> , but it doesnβt say where you can convert void* back to an object.
For most uses, this is a one-way street, but there are some unavoidable uses.
It just says that dynamic_cast<> needs type information in order to convert it back to the requested type.
There are many APIs that require you to pass void* to some object, for example. java / Jni Code passes an object as void* .
If you are pretty sure that the type you entered is correct , you can ask the compiler to make dynmaic_cast<> using a trick.
Take a look at this code:
class Base_Class {public : virtual void dummy() { cout<<"Base\n";} }; class Derived_Class: public Base_Class { int a; public: void dummy() { cout<<"Derived\n";} }; class MostDerivedObject : public Derived_Class {int b; public: void dummy() { cout<<"Most\n";} }; class AnotherMostDerivedObject : public Derived_Class {int c; public: void dummy() { cout<<"AnotherMost\n";} }; int main () { try { Base_Class * ptr_a = new Derived_Class; Base_Class * ptr_b = new MostDerivedObject; Derived_Class * ptr_c,*ptr_d; ptr_c = dynamic_cast< Derived_Class *>(ptr_a); ptr_d = dynamic_cast< Derived_Class *>(ptr_b); void* testDerived = dynamic_cast<void*>(ptr_c); void* testMost = dynamic_cast<void*>(ptr_d); Base_Class* tptrDerived = dynamic_cast<Derived_Class*>(static_cast<Base_Class*>(testDerived)); tptrDerived->dummy(); Base_Class* tptrMost = dynamic_cast<Derived_Class*>(static_cast<Base_Class*>(testMost)); tptrMost->dummy();
Please correct me if this is not the case.