Normally what you do is to implement correctly the copy constructor of each derived class (which in many cases means just leaving just the default one).
Then, you declare in your base class something like
virtual Base* clone()=0;
And in each derived class is implemented as:
virtual Base* clone()
{
return new Derived(*this);
}
Now, each time you want a copy of an object of your class hierarchy just call its clone()
method. This avoids slicing since the version of clone that is called is the one of the actual type, so the correct copy constructor gets called.