C++ Polymorphism: from parent class to child

This question already has an answer here:

  • When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used? 6 answers

  • "but is there any way to convert it back: from parent, which was obtained from child, give child class back?"

    Yes, as mentioned in the other answers, there are two ways to do this.

    Child * old_child = dynamic_cast<Child*>(parent);
    

    The result of the dynamic_cast<> can be checked at runtime, thus you can determine if the parent object really represents a Child instance:

    if(!old_child) {
         // parent is not a Child instance
    }
    

    Also note to get this working properly, the classes in question need to have a vtable, that RTTI can actually determine their relation. The simplest form to achieve this, is giving the Parent class a virtual destructor function

    class Parent {
    public:
        virtual ~Parent() {}
        // or
        // virtual ~Parent() = default;
        // as suggested for latest standards
    };
    

    NOTE:
    If this should apply to a general design decision, I would strongly disregard it. Use pure virtual interfaces instead, that are guaranteed to be implemented, or not.


    The second way of static_cast<> can be used in environments, where you well know that parent actually is a child. The simplest form of this is the CRTP , where Parent takes the inheriting class as a template parameter

    template <class Derived>
    class Parent {
    
         void someFunc() {
             static_cast<Derived*>(this)->doSomething();
         }
    };
    
    class Child : public Parent<Child> {
    public:
        void doSomething();
    };
    

    The validity of an instatiation of Parent<> and static_cast<> will be checked at compile time.

    NOTE:
    Another advantage is that you can use an interface for derived that makes use of

  • static class members of Derived
  • typedef 's provided by Derived
  • ... more class traits, that can be checked at compile time

  • You need to cast the object back to child. This is done like this:

     Child * old_child = static_cast<Child*>(parent);
    

    and

     Child * old_child = dynamic_cast<Child*>(parent);
    

    int main() { 
       Parent parent;
       Child child;
    
       // upcast - implicit type cast allowed
       Parent *pParent = &child; 
    
       // downcast - explicit type case required 
       Child *pChild = (Child *) &parent;
    }
    

    You should use the dynamic_cast to do this safely:

    Child *p = dynamic_cast<Child *>(pParent)
    

    EDIT

    With dynamic_cast returns a null pointer if the type is not apart of the base class, also casting to a reference throws a bad_cast exception. dynamic_cast is particularly useful if you do not know what the object type will be.

    On the other hand static_cast :

    Child *p = static_cast<Child *>(pParent)
    

    This assumes that you want to reverse an explicit conversion and perform no runtime checks. This allows for flexibility but must be used with caution.

    The regular downcast shown above:

    Child *pChild = (Child *) &parent;
    

    Is a C-style down cast (like a static_cast ), which may also cast to a private base class (not sure about, multiple inheritance), while static_cast would cause a compile-time error. Things like numeric conversions is a good example to use this on.

    链接地址: http://www.djcxy.com/p/28694.html

    上一篇: C ++中用于在数字类型之间进行转换的最佳实践

    下一篇: C ++多态性:从父类到子类