Copy object - keep polymorphism
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 any开发者_开发百科thing 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!
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.
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.
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.
Just for the record, this is in the C++ FAQ:
http://www.dietmar-kuehl.de/mirror/c++-faq/abcs.html#faq-22.5
精彩评论