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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…