If the class "owns" the object pointed to by the (abstract) base class pointer, use the Virtual Constructor Idiom in the (abstract) base class. As usual with this idiom, we declare a pure virtual clone() method in the base class:
class Shape {
public:
...
virtual Shape* clone() const = 0; // The Virtual (Copy) Constructor
...
};
Then we implement this clone() method in each derived class. Here is the code for derived class Circle:
class Circle : public Shape {
public:
...
virtual Circle* clone() const;
...
};
Circle* Circle::clone() const
{
return new Circle(*this);
}
(Note: the return type in the derived class is intentionally different from the one in the base class.)
Here is the code for derived class Square:
class Square : public Shape {
public:
...
virtual Square* clone() const;
...
};
Square* Square::clone() const
{
return new Square(*this);
}
Now suppose that each Fred object "has-a" Shape object. Naturally the Fred object doesn't know whether the Shape is Circle or a Square or ... Fred's copy constructor and assignment operator will invoke Shape's clone() method to copy the object:
class Fred {
public:
// p must be a pointer returned by new; it must not be NULL
Fred(Shape* p)
: p_(p) { assert(p != NULL); }
~Fred()
{ delete p_; }
Fred(const Fred& f)
: p_(f.p_->clone()) { }
Fred& operator= (const Fred& f)
{
if (this != &f) { // Check for self-assignment
Shape* p2 = f.p_->clone(); // Create the new one FIRST...
delete p_; // ...THEN delete the old one
p_ = p2;
}
return *this;
}
...
private:
Shape* p_;
};