JohnMcG JohnMcG - 4 months ago 19
C++ Question

What's the best signature for clone() in C++?

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:


  1. Have clone() return a "dumb" pointer, and document that clients are responsible for disposing of it.

  2. Have clone() return a smart base pointer, and have clients use dynamic_cast to save them to a Derived pointer if they need it.



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?

Answer

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.