As Scott Myers wrote, you can take advantage of a relaxation in C++\'s type-system to declare clone() to return a pointer to the actual type being declared:
Tr1::shared_ptr<> can be casted like it were a raw pointer.
I think have clone() return a shared_ptr pointer is a pretty clean solution. You can cast the pointer to shared_ptr by means of tr1::static_pointer_cast or tr1::dynamic_pointer_cast in case it is not possible to determine the kind of cloned object at compile time.
To ensure the kind of object is predictible you can use a polymorphic cast for shared_ptr like this one:
template
inline std::tr1::shared_ptr polymorphic_pointer_downcast(T &p)
{
assert( std::tr1::dynamic_pointer_cast(p) );
return std::tr1::static_pointer_cast(p);
}
The overhead added by the assert will be thrown away in the release version.