How to clone object in C++ ? Or Is there another solution?

156,115

Solution 1

The typical solution to this is to write your own function to clone an object. If you are able to provide copy constructors and copy assignement operators, this may be as far as you need to go.

class Foo
{ 
public:
  Foo();
  Foo(const Foo& rhs) { /* copy construction from rhs*/ }
  Foo& operator=(const Foo& rhs) {};
};

// ...

Foo orig;
Foo copy = orig;  // clones orig if implemented correctly

Sometimes it is beneficial to provide an explicit clone() method, especially for polymorphic classes.

class Interface
{
public:
  virtual Interface* clone() const = 0;
};

class Foo : public Interface
{
public:
  Interface* clone() const { return new Foo(*this); }
};

class Bar : public Interface
{
public:
  Interface* clone() const { return new Bar(*this); }
};


Interface* my_foo = /* somehow construct either a Foo or a Bar */;
Interface* copy = my_foo->clone();

EDIT: Since Stack has no member variables, there's nothing to do in the copy constructor or copy assignment operator to initialize Stack's members from the so-called "right hand side" (rhs). However, you still need to ensure that any base classes are given the opportunity to initialize their members.

You do this by calling the base class:

Stack(const Stack& rhs) 
: List(rhs)  // calls copy ctor of List class
{
}

Stack& operator=(const Stack& rhs) 
{
  List::operator=(rhs);
  return * this;
};

Solution 2

In C++ copying the object means cloning. There is no any special cloning in the language.

As the standard suggests, after copying you should have 2 identical copies of the same object.

There are 2 types of copying: copy constructor when you create object on a non initialized space and copy operator where you need to release the old state of the object (that is expected to be valid) before setting the new state.

Solution 3

If your object is not polymorphic (and a stack implementation likely isn't), then as per other answers here, what you want is the copy constructor. Please note that there are differences between copy construction and assignment in C++; if you want both behaviors (and the default versions don't fit your needs), you'll have to implement both functions.

If your object is polymorphic, then slicing can be an issue and you might need to jump through some extra hoops to do proper copying. Sometimes people use as virtual method called clone() as a helper for polymorphic copying.

Finally, note that getting copying and assignment right, if you need to replace the default versions, is actually quite difficult. It is usually better to set up your objects (via RAII) in such a way that the default versions of copy/assign do what you want them to do. I highly recommend you look at Meyer's Effective C++, especially at items 10,11,12.

Share:
156,115
mert
Author by

mert

Updated on July 02, 2020

Comments

  • mert
    mert almost 4 years

    I wrote a Stack and Queue implementation (Linked List based). There is one stack (bigStack). For example, I separate bigStack (example: stackA and stackB). I pop() a node from bigStack, I push() in stackA. In the same way, I push() in stackB. I want bigStack to not change. Therefore I want to clone the bigStack object. How do I clone objects in C++? Or is there another solution to my problem?

    class Stack : public List {
    public:
       Stack() {}
       Stack(const Stack& rhs) {}
       Stack& operator=(const Stack& rhs) {};
        ~Stack() {}
    
        int Top() {
            if (head == NULL) {
                cout << "Error: The stack is empty." << endl;
                return -1;
            } else {
                return head->nosu;
            }
        }
    
        void Push(int nosu, string adi, string soyadi, string bolumu) {
            InsertNode(0, nosu, adi, soyadi, bolumu);
        }
    
        int Pop() {
            if (head == NULL) {
                cout << "Error: The stack is empty." << endl;
                return -1;
            } else {
                int val = head->nosu;
                DeleteNode(val);
                return val;
            }
        }
    
        void DisplayStack(void);
    
    };
    

    then...

    Stack copyStack = veriYapilariDersi;
    copyStack.DisplayStack();
    
  • John Dibling
    John Dibling over 11 years
    @drceng: You have to actually implement those functions. The code you're provided above does nothing in the methods. The code I posed here is really just psudocode.
  • mert
    mert over 11 years
    I am confused.I code for hours.I didn't see,method isn't do anything :) Ok,I understand.But how to implement ? How to copy construction ?
  • John Dibling
    John Dibling over 11 years
    Does Stack really have no member variables?
  • mert
    mert over 11 years
    Yes.It hasn't.Stack class friend List class.
  • mert
    mert over 11 years
    But my object is initaliazed.Stack is full.I want to clone stack with its nodes.
  • John Dibling
    John Dibling over 11 years
    However note that even with non-polymorphic classes it is not typically necesarry to provide explicit copy constructors or copy assignment operators. The implicit (ie, compiler-provided default) constructor and operator are often sufficient to do the right thing. Since this means there is less code to get wrong, you should not implement these at all unless you actually need to.
  • Kirill Kobelev
    Kirill Kobelev over 11 years
    I do not see data fields in your class. It is not clear what your List is. The info in incomplete. In general you need to copy your object, call same method in your base class. Element of your stack should also copyable.
  • WeirdlyCheezy
    WeirdlyCheezy over 11 years
    @JohnDibling I agree for the most part, but whether or not the defaults provide the correct behavior is heavily dependent on proper use of RAII in the class' fields' types. In a code base that makes heavy use of raw pointers as fields, the default copy/assign will almost never do the right thing. This is one more great argument for proper use of RAII, but sometimes we get stuck maintaining less-than-ideal codebases.
  • Blue Print
    Blue Print about 2 years
    The second snippet I've found valuable.