C++ casting programmatically : can it be done?

后端 未结 8 439
你的背包
你的背包 2021-01-13 06:18

Let\'s say I have a Base class and several Derived classes. Is there any way to cast an object to one of the derived classes without the ne

相关标签:
8条回答
  • 2021-01-13 06:36

    Don't.

    Read up on polymorphism. Almost every "dynamic cast" situation is an example of polymorphism struggling to be implemented.

    Whatever decision you're making in the dynamic cast has already been made. Just delegate the real work to the subclasses.

    You left out the most important part of your example. The useful, polymorphic work.

    string typename = typeid(*object).name();
    if(typename == "Derived1") {
       Derived1 *d1 = static_cast< Derived1*>(object);
       d1->doSomethingUseful();
    }
    else if(typename == "Derived2") {
       Derived2 *d2 = static_cast < Derived2*>(object);
       d2->doSomethingUseful();
    }
    ...
    else {
      ...
    }
    

    If every subclass implements doSomethingUseful, this is all much simpler. And polymorphic.

    object->doSomethingUseful();
    
    0 讨论(0)
  • 2021-01-13 06:36

    Your example won't port, because the exact format of name() isn't specified. You could try a succession of dynamic_casts. Dynamic_cast returns a null pointer if you cast to the wrong type. However, if you're doing a typeswitch like this one, there's something wrong with your design.

    0 讨论(0)
  • 2021-01-13 06:43

    You can use dynamic_cast and test for NULL, but I'd strongly consider refactoring the code instead.

    If you need subclass-specific handling, Template Method might be helpful, but without knowing what you're trying to achive, it's only a vague guess.

    0 讨论(0)
  • 2021-01-13 06:44

    usually, this is a sign of a bad design. Why do you need to do this? It might be possible to redesign so that this is not needed.

    0 讨论(0)
  • 2021-01-13 06:46
    Derived1* d1 = dynamic_cast< Derived1* >(object);
    if (d1 == NULL)
    {
        Derived2* d2 = dynamic_cast< Derived2* >(object);
        //etc
    }
    

    I have the following methods on my smartpointer type, simulating C# 'is' and 'as':

    template< class Y > bool is() const throw()
        {return !null() && dynamic_cast< Y* >(ptr) != NULL;}
    template< class Y > Y* as() const throw()
        {return null() ? NULL : dynamic_cast< Y* >(ptr);}
    
    0 讨论(0)
  • 2021-01-13 06:46

    You can do this using dynamic_cast, e.g:

    if ( Derived1* d1 = dynamic_cast<Derived1*>(object) ) {
        // object points to a Derived1
        d1->foo();
    }
    else if ( Derived2* d2 = dynamic_cast<Derived2*>(object) ) {
        // object points to a Derived2
        d2->bar();
    }
    else {
        // etc.
    }
    

    But as others have said, code such as this can indicate a bad design, and you should generally use virtual functions to implement polymorphic behaviour.

    0 讨论(0)
提交回复
热议问题