#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Posts
    9
    Rep Power
    0

    C++ (Object Cloning)


    How would you write a C++ function that clones an object. I know the usual way to handle this is to write a copy constructor for your class. But lets suppose you just want to right a generic method clone that takes an object as its argument and returns a clone of it.

    Forexample

    SomeClass* c1= new SomeClass( );

    SomeClass* clone1= clone( c1 );

    and clone1 would be a clone of c1.

    This task is easy in Java. All that would be required is that you override the clone method inherited from Object and extend the cloneable interface. Is there any way to write a method like this in c++????
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,481
    Rep Power
    15
    "Is there any way to write a method like this in c++????

    I know the usual way to handle this is to write a copy constructor for your class. "

    Is there any way to write a method like this in c++????

    A copy constructor is just a function that clones objects(and is not allowed to have a return type). For your function, just use a different name than the copy constructor, and have it return a pointer to the object you dynamically create.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Posts
    9
    Rep Power
    0
    I dont quit understand your reply. Perhaps my question wasnt clear. What I mean is could a function clone() be created which does not belong to any particular class (in other words is not a member function) and this function will clone any object passed to it???
  6. #4
  7. No Profile Picture
    status unknown
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2003
    Posts
    262
    Rep Power
    12
    Why not try it? You already know the signature of the function you're after. You pass it an object and return a newly created copy of that object. It should be able to accept any type of object, so some form of templated function sounds likely. I would suggest you write it for a specific type of object first, then template it.
  8. #5
  9. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,607
    Rep Power
    4247
    >> What I mean is could a function clone() be created which does not belong to any particular class (in other words is not a member function) and this function will clone any object passed to it???

    Templates are the way to go here. That and the new keyword should be all you need.
    Code:
    template <class T>
    T *clone(T orig)
    {
      T *copy = new T();
    
      *copy = orig;
      return copy;
    }
    Last edited by Scorpions4ever; August 10th, 2003 at 12:13 PM.
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  10. #6
  11. No Profile Picture
    status unknown
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2003
    Posts
    262
    Rep Power
    12
    You can improve it still further with:

    Code:
    template <typename T>
    T* clone(const T& orig)
    {
        T* temp = new T();
        *temp = orig;
        return temp;
    }
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Posts
    9
    Rep Power
    0
    This code will only give a shollow copy of the object
    code:--------------------------------------------------------------------------------
    template <class T>
    T *clone(T orig)
    {
    T *copy = new T();

    *copy = orig;
    return copy;
    }

    it is really only returning an object that refers to the same object passed to it.

    How would you make a real copy of your object passed to the funtion????? That is without knowing any details of what is passed to it. In other words your clone function will have to make this sample code work



    class CloneClass
    {
    private:
    int i;

    public:
    CloneClass( int I )
    {
    i=I;
    }

    CloneClass( const CloneClass& Other )
    : i( Other.i )
    {}

    int getI() const
    {
    return i;
    }
    };

    int main( int argv, char** argc )
    {
    CloneClass* c1= new CloneClass( 4 );

    CloneClass* clone1= clone( c1 );

    cout << "c1->i = " << c1->getI() << endl;
    cout << "clone1->i = " << clone1->getI() << endl;
    cout << "c1==clone1 = " << ((c1==clone1)?"true":"false") <<
    endl;
    }
  14. #8
  15. No Profile Picture
    status unknown
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2003
    Posts
    262
    Rep Power
    12
    Originally posted by masterM
    This code will only give a shollow copy of the object
    code:--------------------------------------------------------------------------------
    template <class T>
    T *clone(T orig)
    {
    T *copy = new T();

    *copy = orig;
    return copy;
    }

    it is really only returning an object that refers to the same object passed to it.

    How would you make a real copy of your object passed to the funtion????? That is without knowing any details of what is passed to it.
    I'm not sure what you're saying here. It sounds as though you're mistaken. The code posted by Scorpions4ever (and mine) will indeed make a new object that is a copy of the original, not simply an object that refers to the original. You end up with two objects, the original and the new copy.

    You don't need to know any details about the type of object passed to it, the compiler does that for you. That's the beauty of templates.
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,481
    Rep Power
    15
    Code:
    This code will only give a shollow copy of the object:
    
    template <class T> 
    T *clone(T orig) 
    { 
         T *copy = new T(); 
    
        *copy = orig; 
          return copy; 
    }
    True.

    it is really only returning an object that refers to the same object passed to it.
    False. The code creates a new location in memory and then assigns a copy of the original(passed-by-value) to that location. The second example just uses a reference to avoid the pass by value copying, and once again a shallow copy is made to the dynamically allocated memory.

    What is happening is that the compiler is providing a default assignment operator for your class. If you want a deep copy, you need to define your own assignment operator for your class.

    Your own example is not a good one because your class has no reference or pointer data members, so a shallow copy would be fine. Finally, for this line to work:

    c1==clone1

    You have to define the == operator in your class because the compiler doesn't know how to compare two objects of a class unless you tell it--there is no default member by member comparison similar to what happens with the default assignment operator when the compiler copies member by member.
    Last edited by 7stud; August 10th, 2003 at 05:05 PM.

IMN logo majestic logo threadwatch logo seochat tools logo