CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Nov 2010
    Posts
    54

    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?

  2. #2
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    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
    }
    Last edited by Igor Vartanov; July 24th, 2014 at 02:01 PM.
    Best regards,
    Igor

  3. #3
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    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.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  4. #4
    Join Date
    Jul 2013
    Posts
    576

    Re: How to clone an object in C++?

    Quote Originally Posted by AlanCCC View Post
    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.
    Last edited by razzle; July 28th, 2014 at 12:21 AM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured