Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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?

like image 867
JohnMcG Avatar asked Nov 03 '08 20:11

JohnMcG


People also ask

What is a c++ signature?

C++ Reference. Programming Terms. Function Signatures. A function signature consists of the function prototype. What it tells you is the general information about a function, its name, parameters, what scope it is in, and other miscellaneous information.

Which options are valid for calling a copy constructor?

In C++, a Copy Constructor may be called for the following cases: 1) When an object of the class is returned by value. 2) When an object of the class is passed (to a function) by value as an argument. 3) When an object is constructed based on another object of the same class.

Why is copy constructor called reference?

A copy constructor defines what copying means,So if we pass an object only (we will be passing the copy of that object) but to create the copy we will need a copy constructor, Hence it leads to infinite recursion. So, A copy constructor must have a reference as an argument.

Can copy constructor be virtual in C++?

No you can't, constructors can't be virtual.


3 Answers

Use the Public non-virtual / Private virtual pattern :

class Base {
    public:
    std::auto_ptr<Base> clone () { return doClone(); }
    private:
    virtual Base* doClone() { return new (*this); }
};
class Derived : public Base {
    public:
    std::auto_ptr<Derived> clone () { return doClone(); }
    private:
    virtual Derived* doClone() { return new (*this); }
};
like image 52
MSalters Avatar answered Dec 22 '22 07:12

MSalters


The syntax isn't quite as nice, but if you add this to your code above, doesn't it solve all your problems?

template <typename T>
std::auto_ptr<T> clone(T const* t)
{
    return t->clone();
}
like image 22
Matt Cruikshank Avatar answered Dec 22 '22 07:12

Matt Cruikshank


I think the function semantics are so clear in this case that there is little space for confusion. So I think you can use the covariant version (the one returning a dumb pointer to the real type) with an easy conscience, and your callers will know that they are getting a new object whose property is transferred to them.

like image 22
Gorpik Avatar answered Dec 22 '22 08:12

Gorpik