Thread: Clone function

  1. #1
    Disturbed Boy gustavosserra's Avatar
    Join Date
    Apr 2003
    Posts
    244

    Clone function

    Hi everyone!
    I canīt seem to figure out how to do correctly a clone function to an object. I searched through the board, but found nothing.

    One wrong way woule be:
    Code:
    const X& clone(){
    	return X(/*attributes*/);	
    }
    But at the end of the clone function, the object is destroyied, deallocating any other object inside of it.
    Other way:
    Code:
    const X& clone(){
    	X* temp = new X(/*attributes*/);
    	return *temp;	
    }
    But then, the object isnīt deallocated...
    How can I do it?
    Thanks any help!
    Nothing more to tell about me...
    Happy day =)

  2. #2
    Registered User
    Join Date
    Dec 2002
    Posts
    119
    Well, maybe there's something special about a "clone" function that I havn't heard of, but if you want to be able to copy an instance of a class then I suggest searching the board & google for overload assignment operator and copy constructor. If you want a function to generate a "clone" you could use the dynamic memory allocation and then in your documentation state that the client needs to delete the object when done. OR create an instance of the object, pass it to the clone function to be cloned with all the values of the instance of the class being cloned.
    If you speak or are learning Spanish, check out this Spanish and English Dictionary, it is a handy online resource.
    What happens is not as important as how you react to what happens. -Thaddeus Golas

  3. #3
    Programming Sex-God Polymorphic OOP's Avatar
    Join Date
    Nov 2002
    Posts
    1,078
    If you want to use the clone function polymorphically then make it return a pointer and dynamically allocate a copy from within the function. Yes, this does mean that the user is responsible for deallocating the object. Then, using covariant return types, your function will return a pointer to the child type when called from a pointer to the child and will return a pointer to the base when called from the base:

    Code:
    class base
    {
    public:
      virtual base* clone() const
      {
        return new base;
      }
      virtual ~base() {}
    };
    
    class child
      : public base
    {
    public:
      child* clone() const
      {
        return new child;
      }
    };
    
    int main()
    {
      base base_inst;
      child child_inst;
    
      base& child_ptr = child_inst;
    
      child* Test0 = child_inst.clone(), // works
           * Test1 = base_inst.clone(),  // doesn't work
           * Test2 = child_ptr.clone();  // doesn't work  
    
      delete Test0;
      delete Test1;
      delete Test2;
    }
    Also, as a side note, MSVC++ .NET 2003 does NOT support co-variant return types when you are dealing with virtual base classes.

  4. #4
    Disturbed Boy gustavosserra's Avatar
    Join Date
    Apr 2003
    Posts
    244
    Thank you both. But, I do not want to pass the object that will receive the clone because is not "clean". I do not want to use a pointer, because I already know. For better explanation, I copied the prototype of the copy function of the string class:
    Code:
    string copy() const throw( xalloc )
    Notice that it returns an object, so, probaly, at the end of the function there is something like:
    Code:
    return string("old string");
    But, trying to make an example to show what I meant I discovered what was my error:

    I was returning a const reference before:
    Code:
    const X& clone(){ return X(); }
    For some reason, the destructor of the object created on return is called before any attribution.
    But now:
    Code:
    X clone(){ return X(); }
    Works fine...
    *sigh* I do not know why this happens :-(
    Anyway, thanks again.
    Nothing more to tell about me...
    Happy day =)

  5. #5
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    To understand what is happening, look at this example:
    Code:
    class X
    {
        int i_;
    public:
        X(int i) : i_(i) { }
    };
    
    const X& clone1() { return X(1); }
    X clone2() { return X(2); }
    
    int main()
    {
        X x1 = clone1();
        X x2 = clone2();
    }
    For x1, clone1 is returning a reference to the temporary variable created inside its return statement. As soon as that return statement completes, the temporary variable goes out of scope and is destroyed, so your x1 variable is referencing a destroyed object.

    On the other hand, clone2 returns a new object that is a copy of the temporary variable created inside the return statement. This copy is made using the copy constructor (either the default copy constructor or one you add to the class). Since x2 is only a copy of and not a reference to the temporary variable, it is still valid after the temporary is destroyed.

    I do wonder whether you want clone() to be called only in certain situations where you know the source is not "clean", or you never want the copy constructor or operator= to be called. If it is the second case, I'm not sure why, since you can just make the copy constructor and operator= do the same thing as clone() is doing. I ask because your version of clone might be doing things you don't want it to do with the implicit call to the copy constructor and/or operator=.

  6. #6
    ĄAmo fútbol!
    Join Date
    Dec 2001
    Posts
    2,138
    Quite simply, one returns a reference to a variable. However, the variable to which it is pointing (b/c a reference is similar to a pointer) is destroyed. The other is returning an object itself, not a reference. Hence, the object is not destroyed b/c it is the one actually being returned.

  7. #7
    Disturbed Boy gustavosserra's Avatar
    Join Date
    Apr 2003
    Posts
    244
    jlou, the clone function was an exercise from a book. The "clean" is just about passing the object that will receive the clone as a parameter.
    golfinguy4, I read that the return object() is, actually a syntax. The compiler, seeing that return wll call the copy constructor of the lvalue.
    Thanks you both!
    Nothing more to tell about me...
    Happy day =)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Beginner Needs help in Dev-C++
    By Korrupt Lawz in forum C++ Programming
    Replies: 20
    Last Post: 09-28-2010, 01:17 AM
  2. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  3. is it possible to pass arguments to the clone fn function?
    By smoking81 in forum Linux Programming
    Replies: 4
    Last Post: 09-12-2008, 10:27 AM
  4. In over my head
    By Shelnutt2 in forum C Programming
    Replies: 1
    Last Post: 07-08-2008, 06:54 PM
  5. Including lib in a lib
    By bibiteinfo in forum C++ Programming
    Replies: 0
    Last Post: 02-07-2006, 02:28 PM