复制对象 - 保持多态性

时间:2010-11-08 10:00:05

标签: c++ inheritance pointers polymorphism

以下代码尝试复制对象并保留原始类型。 不幸的是它不起作用(每个复制的对象都将成为Super而不是与原始对象相同的类。

请注意,copySuper(const Super& givenSuper)不应该对Super的子类有任何了解。

有可能做这样的副本吗?或者我是否必须更改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!

4 个答案:

答案 0 :(得分:12)

试试这个:

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

请注意,我们已经实现了一个clone()函数,Special(以及Super的任何其他衍生物)覆盖以创建正确的副本。

e.g:

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

编辑:正如其他评论员指出的那样,*this,而不是this。那会教我快速输入。

EDIT2:另一次更正。

编辑3:我真的不应该在工作中间这么快发帖。为协变返回类型修改了Special :: clone()的返回类型。

答案 1 :(得分:3)

您想要的通常是使用基类中的抽象clone方法实现的。 Special通常会返回new Special(*this)

来实现此方法

另请注意,将基类设为不可复制是最佳做法。

答案 2 :(得分:3)

这就是你需要的:

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();
}

以前的一个示例中派生类的克隆错误。以上是实现克隆方法的正确方法。

答案 3 :(得分:3)