Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 复制对象-保持多态性_C++_Inheritance_Pointers_Polymorphism - Fatal编程技术网

C++ 复制对象-保持多态性

C++ 复制对象-保持多态性,c++,inheritance,pointers,polymorphism,C++,Inheritance,Pointers,Polymorphism,以下代码尝试复制对象并保留原始类型。 不幸的是,它不起作用(每个复制的对象都将成为Super,而不是与原始对象属于同一类) 请注意,copySuper(const Super&givenSuper)不应该知道关于Super的子类的任何信息 有可能复印这样一份吗?或者我必须更改copySuper的定义吗 #include <string> #include <iostream> class Super { public: Super() {}; virtu

以下代码尝试复制对象并保留原始类型。 不幸的是,它不起作用(每个复制的对象都将成为
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!
#包括
#包括
超级班
{
公众:
超级(){};
虚~Super(){};
虚拟std::string toString()常量
{
返回“我超级棒!”;
}
};
特别类:公共超级
{
公众:
特别{};
虚拟的~Special(){};
虚拟std::string toString()常量
{
返回“我很特别!”;
}
};
超级*复制超级(const Super和givenSuper)
{
超级*超级副本(新超级(givenSuper));
返回超拷贝;
}
int main()
{
特别的;
std::cout试试这个:

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()函数,该函数使用特殊(以及Super的任何其他派生)重写来创建正确的副本

e、 g:

编辑:正如其他评论员所指出的,
*这个
,而不是
这个
。这将教会我快速打字

编辑2:又一次更正


< P> > EdTe3:我真的不应该在工作中间这么快地发布。修改后的返回类型:CyOne()用于协变返回类型。

基本上是使用基类中的抽象<代码>克隆< /代码>方法来实现的。特别是通常通过返回<代码>新的特殊(*this)< /C> > < /P>实现此方法。
还请注意,使基类不可压缩被认为是最佳做法。

这就是您需要的:

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

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

< P>只是对于记录,这是在C++ FAQ:


不应编译此的可能副本,因为至少指定了一个构造函数,但没有指定副本构造函数。这至少可以用VS 2008编译。你是对的。我感到困惑。哦,没有什么新的。正是我要说的+1@Moo:同时更正此行。特殊*b=b->clone();//a的副本它应该是a->clone();还有一件事。您的代码将无法编译,因为这一行'Super()/regular ctor'恐怕我不能为此承担责任。我发誓编辑有时会对我发火,因为这在发布时是正确的。无论如何,感谢你指出这一点。+1,尽管我会在每个对象中将复制构造函数和赋值操作符设置为受保护的,因为它们的无意使用可能会导致对象切片。我还要注意,
return
是一个关键字,而不是一个函数,我们可以不使用两个额外的括号。@Moo Juice您的Special::clone()方法返回Super*,这是错误的。Special::clone()的正确返回非常特别,这肯定会教我如何匆忙发帖,非常感谢。我已经更正了我的帖子。
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();
}