How to clone an object in C++?
I define two classes in C++, as follows:
class CBaseClass
{
…
}
class CDerivedClass : public CBaseClass
{
…
}
And want to implement a clone function as follows:
CBaseClass *Clone(const CBaseClass *pObject)
{
}
When an object of CDerivedClass is passed to Clone, then the function will also create a CDerivedClass object and return.
When an object of CBaseClass is passed to Clone, then the function will also create a CBaseClass object and return.
How to implement such a feature?
Re: How to clone an object in C++?
Every class which objects to be cloned needs to implement copy constructor. Then the basic generalized function should look like:
Code:
template <class T>
T* CBaseClass::Clone(const T& obj)
{
return new T(obj); // here copy constructor gets called
}
Re: How to clone an object in C++?
Quote:
Originally Posted by AlanCCC
And want to implement a clone function as follows:
CBaseClass *Clone(const CBaseClass *pObject)
{
}
When an object of CDerivedClass is passed to Clone, then the function will also create a CDerivedClass object and return.
When an object of CBaseClass is passed to Clone, then the function will also create a CBaseClass object and return.
How to implement such a feature?
I suggest this instead:
Code:
class CBaseClass
{
public:
// ...
virtual CBaseClass* Clone() const
{
return new CBaseClass(*this);
}
// ...
};
class CDerivedClass : public CBaseClass
{
public:
// ...
virtual CDerivedClass* Clone() const
{
return new CDerivedClass(*this);
}
// ...
};
Notice that the implementation is similiar to Igor Vartanov's Clone member function template suggestion, except that the Clone member function has no parameters and is a virtual member function instead of a member function template, hence the point that "every class which objects to be cloned needs to implement copy constructor" remains. Notice also that the derived class' version has a different return type, i.e., the use of covariant return types comes into play.
The advantage here is that given a pointer p to an object of a class in this hierarchy, you clone the object with p->Clone() instead of p->Clone(*p), which is important since p might be a CBaseClass* that points to a CDerivedClass object, in which case p->Clone(*p) will result in unwanted object slicing whereas p->Clone() will clone the CDerivedClass object.
Re: How to clone an object in C++?
Quote:
Originally Posted by
AlanCCC
How to implement such a feature?
In OO programming the relationship between CBaseClass and CDerivedClass would be characterized as "inheritance of implementation" (because CbaseClass carries implementation). None of these classes would ever be exposed to uses code (because publicly exposed inheritance of implementation leads to a brittle design). Instead an abstract interface would be introduced, say IClass. It would be defined something like this,
Code:
class IClass { // abstract public interface
public:
virtual ~IClass() {} // virtual destruction
IClass(const IClass&) = delete; // no copy
IClass& operator=(const IClass&) = delete;
IClass(const IClass&&) = delete; // no move
IClass& operator=(const IClass&&) = delete;
...
virtual IClass* Clone() =0; // cloning rather than copying
...
protected:
IClass() = default; // no public construction
};
Public copying and moving are disabled and so is public construction.
Then CBaseClass would inherit IClass like,
class CBaseClass : public IClass // top hidden implementation class
{
…
}
Finally CBaseClass would implement Clone() and CDerivedClass and other derived classes could override it if they wanted.
So the only thing uses code would ever see is IClass. CBaseClass and CDerivedClass would be considered implementation classes and kept out of sight.
Typically, in real code objects of the IClass type would be handled by "smart" pointer to ease memory management.