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:
class Base
{
virtual Base* clone() const = 0;
};
class Derived : public Base
{
virtual Derived* clone() const
};
The compiler detects that clone() returns an pointer to the type of the object, and allows Derived to override it to return a pointer to derived.
It would desirable to have clone() return a smart pointer that implies transfer of ownership semantics, like the following:
class Base
{
virtual std::auto_ptr<Base> clone() const = 0;
};
class Derived : public Base
{
virtual std::auto_ptr<Derived> clone() const;
};
Unfortunately, the relaxation of the conventions does not apply to templated smart pointers, and the compiler will not allow the override.
So, it seems I am left with two options:
Is one of these approaches preferred? Or is there a way for me to eat my transfer of ownership semantics and have my strong type safety too?
It depends on your use case. If you ever think you will need to call clone
on a derived object whose dynamic type you know (remember, the whole point of clone
is to allow copying without knowing the dynamic type), then you should probably return a dumb pointer and load that into a smart pointer in the calling code. If not, then you only need to return a smart_ptr and so you can feel free to return it in all overrides.