Polymorphic copy-constructor with type conversion

后端 未结 4 1574
遇见更好的自我
遇见更好的自我 2021-01-26 11:18

I need to copy-construct an object simultaneously changing it\'s type to another class being a member of the same class-hierarchy. I\'ve read about polymorphic copy-constructors

相关标签:
4条回答
  • 2021-01-26 11:40

    If you only have 2 child classes, then the easiest way is to create a conversion constructor:

    class Child2: public Base
    {
    public: 
        Child2(Child1 const& child)
        {
                p_int = new int (*child.p_int);
                a = child.a + 1;        
        }
    }; 
    
    c2 = new Child2(*c1); 
    

    If you have several Child classes, and you need to create a Child2 from any of them, then you could do something like this:

    class Base
    {
    public: 
        void CopyFrom(Base* base)
        {
                p_int = new int (*base.p_int);
                a = base.a + 1;     
        }
    }; 
    
    class ChildX: public Base
    {
    public: 
        static ChildX* CreateFrom(Base* base)
        {
            ChildX ch = new ChildX(); 
            ch->CopyFrom(base); 
            return ch; 
        }
    }; 
    
    c2 = Child2::CreateFrom(c1); 
    
    0 讨论(0)
  • 2021-01-26 11:47

    The clone() patterns allows you to create a valid copy/clone of the object of a child class having just the base reference, e.g. in your case it allows you to do the following:

    Base* basePtr = getBaseOrSomeDerivedObject();
    Base* copy = basePtr.clone(); // Create a copy that is an object of an actual basePtr's type.
    

    What you could need is a "copy-constructor" that allows you to copy from a base class, e.g.:

    class Base {
    public:
        // [...]    
        Base(const Base& other) : a(other.a + 1)
        {
            p_int = new int(*(other.p_int));
        }
        // [...]
    };
    
    
    class Child2 : public Base {
    public:
        // [...]
        Child2(const Base& base) : Base(base) {}
        // [...]
    };
    
    int main() {
        // [...]
        c2 = new Child2(*c1);
        c2->print();
    }
    

    Result:

    Child1: 7275360:4 0
    Child2: 7340936:4 1
    
    0 讨论(0)
  • 2021-01-26 11:52
    c2 = (Child2*)c1->clone();
    

    Here is a serious bug, and the c-style cast hides the bug.

    If you use C++-style cast, then it will not hide the bug, and you will know it. In this case, the C++-style cast is : dynamic_cast. Use it to discover the bug yourself.

    As it is clear from the code thatc1-clone() creates a clone of c1 whose type is Child1* and clone() returns a pointer of type Base* (after upcasting from Child1*), which you're trying to down-cast to Child2*. The cast should fail if you use proper cast : dynamic_cast.

    0 讨论(0)
  • 2021-01-26 11:54

    Simplest solution would probably be to implement a Child2 constructor taking a Child1& as parameter. Then you could simply call:

    Child2* c2 = new Child2(*c1);
    
    0 讨论(0)
提交回复
热议问题