Are there practical uses for dynamic-casting to void pointer?

后端 未结 7 1289
隐瞒了意图╮
隐瞒了意图╮ 2020-11-27 14:00

In C++, the T q = dynamic_cast(p); construction performs a runtime cast of a pointer p to some other pointer type T that must

7条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-11-27 14:35

    Casting pointers to void* has its importance since way back in C days. Most suitable place is inside the memory manager of Operating System. It has to store all the pointer and the object of what you create. By storing it in void* they generalize it to store any object on to the memory manager data structure which could be heap/B+Tree or simple arraylist.

    For simplicity take example of creating a list of generic items(List contains items of completely different classes). That would be possible only using void*.

    standard says that dynamic_cast should return null for illegal type casting and standard also guarantees that any pointer should be able to type cast it to void* and back from it with only exception of function pointers.

    Normal application level practical usage is very less for void* typecasting but it is used extensively in low level/embedded systems.

    Normally you would want to use reinterpret_cast for low level stuff, like in 8086 it is used to offset pointer of same base to get the address but not restricted to this.

    Edit: Standard says that you can convert any pointer to void* even with dynamic_cast<> but it no where states that you can not convert the void* back to the object.

    For most usage, its a one way street but there are some unavoidable usage.

    It just says that dynamic_cast<> needs type information for converting it back to the requested type.

    There are many API's that require you to pass void* to some object eg. java/Jni Code passes the object as void*.
    Without type info you cannot do the casting.If you are confident enough that type requested is correct you can ask compiler to do the dynmaic_cast<> with a trick.

    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(ptr_c);
            void* testMost = dynamic_cast(ptr_d);
            Base_Class* tptrDerived = dynamic_cast(static_cast(testDerived));
            tptrDerived->dummy();
            Base_Class* tptrMost = dynamic_cast(static_cast(testMost));
            tptrMost->dummy();
            //tptrMost = dynamic_cast(static_cast(testMost));
            //tptrMost->dummy(); //fails
    
        } catch (exception& my_ex) {cout << "Exception: " << my_ex.what();}
        system("pause");
      return 0;
    }
    

    Please correct me if this is not correct in any way.

提交回复
热议问题