How to Clone as Derived Object in C++

Clone derived class from base class pointer

I also think you probably cannot improve the code in the sense to make it shorter.
I would say this implementation is basically the way to go.

What you could do is to change the return value of Derived::clone to Derived *. Yes C++ allows this.

Then a direct use of Derived::clone yields the correct pointer type and Base::clone still works as expected

class Derived : public Base
{
public:
Derived()
{
a = 8;
}

Derived* vclone() const override // <<--- 'Derived' instead of 'Base'.
{
return new Derived(*this);
}
};

I would also rename to vclone member function to clone (There is no need to have two names).

The free function clone could be made a template so that it works for all classes and returns the right pointer type

template <class T>
T *clone(const T *cls)
{
return cls->clone();
}

However, all these changes do not make the code shorter, just more usable and perhaps more readable.

To make it a little shorter you might use an CRTP approach.

template <class Derived, class Base>
class CloneHelper: public Base {
Derived* vclone() const override
{
return new Derived(* static_cast<Derived *>(this) );
}
};
// then use
class Derived : public CloneHelper<Derived, Base>
{
public:
Derived()
{
a = 8;
}
};

However, I am not sure if it is worth it. One still must not forget the CloneHelper, it makes inheritance always public and you cannot delegate to the Base constructor so easily and it is less explicit.

C++ elegantly clone derived class by calling base class

You could always stick all the cloning logic into its own class in the middle of the hierarchy:

template <class Derived, class Base>
class CloneCRTP : public Base {
public:
Derived* clone() const override {
return new Derived(static_cast<Derived const&>(*this));
}
};

And then:

class B : public CloneCRTP<B, A>
{
int i;
public:
virtual ~B() { cout << "destroyed b" << endl; }
};

No more boilerplate.

Clone derived class from base class method

Just override the Clone and have another method to CreateInstance then do your stuff.

This way you could have only Base class avoiding generics.

public Base
{
protected int field1;
protected int field2;
....

protected Base() { ... }

public virtual Base Clone()
{
var bc = CreateInstanceForClone();
bc.field1 = 1;
bc.field2 = 2;
return bc;
}

protected virtual Base CreateInstanceForClone()
{
return new Base();
}
}

public A : Base
{
protected int fieldInA;
public override Base Clone()
{
var a = (A)base.Clone();
a.fieldInA =5;
return a;
}

protected override Base CreateInstanceForClone()
{
return new A();
}
}

Cloning a derived type more elegantly

You could use the CRTP:

template <typename Derived>
struct derived_base : base
{
Derived* clone()
{
Derived* x = new Derived;
// ...
return x;
}
};

struct derived : derived_base<derived> {}

C++: Deep copying a Base class pointer

You need to use the virtual copy pattern: provide a virtual function in the interface that does the copy and then implement it across the hierarchy:

struct base {
virtual ~base() {} // Remember to provide a virtual destructor
virtual base* clone() const = 0;
};
struct derived : base {
virtual derived* clone() const {
return new derived(*this);
}
};

Then the DeepCopy object just needs to call that function:

class DeepCopy 
{
Base * basePtr;
public:
DeepCopy(DeepCopy const & dc) // This should be `const`
: basePtr( dc.basePtr->clone() )
{}
};


Related Topics



Leave a reply



Submit