Copy object - keep polymorphism

橙三吉。 提交于 2019-12-17 16:33:37

问题


The following code tries to copy an object and keep the original type. Unfortunately it does not work (every copied object will become a Super instead of being of the same class as its original).

Please note that copySuper(const Super& givenSuper) should not know anything about the subclasses of Super.

Is it possible to do such a copy? Or do I have to change the definition of copySuper ?

#include <string>
#include <iostream>

class Super
{
public:
    Super() {};
    virtual ~Super() {};

    virtual std::string toString() const
    {
        return "I'm Super!";
    }
};

class Special : public Super
{
public:
    Special() {};
    virtual ~Special() {};

    virtual std::string toString() const
    {
        return "I'm Special!";
    }
};

Super* copySuper(const Super& givenSuper)
{
    Super* superCopy( new Super(givenSuper) );
    return superCopy;
}

int main()
{
    Special special;
    std::cout << special.toString() << std::endl;

    std::cout << "---" << std::endl;

    Super* specialCopy = copySuper(special);
    std::cout << specialCopy->toString() << std::endl;

    return 0;
}

//Desired Output:
// # I'm Special!
// # ---
// # I'm Special!
//
//Actual Output:
// # I'm Sepcial!
// # ---
// # I'm Super!

回答1:


Try this:

class Super
{
public:
    Super();// regular ctor
    Super(const Super& _rhs); // copy constructor
    virtual Super* clone() const {return(new Super(*this));};
}; // eo class Super


class Special : public Super
{
public:
    Special() : Super() {};
    Special(const Special& _rhs) : Super(_rhs){};
    virtual Special* clone() const {return(new Special(*this));};
}; // eo class Special

Note that we have implemented a clone() function that Special (and any other derivative of Super) overrides to create the correct copy.

e.g:

Super* s = new Super();
Super* s2 = s->clone(); // copy of s
Special* a = new Special();
Special* b = a->clone(); // copy of a

EDIT: As other commentator pointed out, *this, not this. That'll teach me to type quickly.

EDIT2: Another correction.

EDIT3: I really should not post so quickly when in the middle of work. Modified return-type of Special::clone() for covariant return-types.




回答2:


This is what you need :

class Super
{
    public:
        Super()
        {
        }

        virtual Super* clone() const
        {
            return( new Super(*this) );
        };
};


class Special : public Super
{
    public:
        Special() : Super()
        {
        };
        Special(const Special& _rhs) : Super(_rhs)
        {
        };
        virtual Special* clone() const
        {
            return( new Special( *this ) );
        };
};

int main()
{
    Special a;
    Super &c( a );
    Super *b1 = c.clone();
    Special *b2 = a.clone();
    Super *b3 = a.clone();
}

One of previous examples has the clone for derived class wrong. The above is correct way of implementing the clone method.




回答3:


What you want is generally implemented using an abstract clone method in the base class. Special will typically implement this method by returning new Special(*this).

Also note that it is considered a best practice to make base classes uncopyable.




回答4:


Just for the record, this is in the C++ FAQ:

http://www.dietmar-kuehl.de/mirror/c++-faq/abcs.html#faq-22.5



来源:https://stackoverflow.com/questions/4122789/copy-object-keep-polymorphism

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!