Shallow and Deep Copy in C++

What is Shallow and Deep Copy in C++ ?

When using copy constructors, shallow copy is when objects share same memory locations for variables. While deep copy is when objects have their own individual memory locations

Shallow and deep Copy in Cpp

Difference between Shallow and Deep Copy

We recommend going through what is copy constructor in C++ page before moving ahead with this post

Shallow Copy

Shallow Copy

Whenever we do not create our own user-defined copy constructor and we do copying, the compiler creates its own hidden copy constructor.

  • Whenever this happens the member variables etc share the same memory locations.
  • Any change in object1 is also reflected in object2

This default copy constructor does shallow copy. The code below reflects what happens in shallow copy.

Deep Copy

Deep Copy

Whenever we create our own user-defined copy constructor and we do the copying.

  • Whenever this happens the member variables etc for any objects have their own memory locations.
  • For example, any change in object1 is not reflected in object2

User-defined copy constructor do a deep copy. Code below reflects what happens in shallow copy

Shallow Copy Example

#include<iostream>
using namespace std; 
  
class PrepInsta 
{
    int *var;
    public:

    // Parmeterized constructor
    PrepInsta(int x) {
        var = new int;
        *var = x; 
    }
    
    // setter
    void setValue(int val){
        *var = val;
    }
    
    // getter
    int getValue(){
        return *var;
    }
  
    // the compiler would create its own hidden copy constructor
    // as we have not created our own user defined copy constructor here
    // shallow copy will happen i.e. objects variables etc will share memory

}; 
  
int main() 
{
    // calling the normal constructor
    PrepInsta obj1(10);
    
    // calling default copy constructor of compiler (Shallow Copy)
    PrepInsta obj2 = obj1; 
  
    cout << "Before value change - " << endl;
    
    // printing the values, assigned by constructors
    cout << "obj1.var = " << obj1.getValue() << endl; 
    cout << "obj2.var = " << obj2.getValue() << endl;
    
    obj1.setValue(20);
    
    cout << "\nAfter value change - " << endl;
    
    // printing the values, assigned by constructors
    cout << "obj1.var = " << obj1.getValue() << endl; 
    cout << "obj2.var = " << obj2.getValue() << endl;
    
    // since we did shallow copy as we didnt make any
    // user defined copy constructor
    // change in obj1 is reflected in obj2

    return  0; 
}

Output

Before value change - 
obj1.var = 10
obj2.var = 10

After value change - 
obj1.var = 20
obj2.var = 20

Deep Copy Example

#include<iostream>
using namespace std; 
  
class PrepInsta 
{ 
public:
    int var; 
    
    PrepInsta(int x) {
        var = x; 
    } 
  
    // Overriding default copy constructor 
    // with user defind copy contructor
    PrepInsta(const PrepInsta &obj) {
        var = obj.var; 
    }
}; 
  
int main() 
{
    // calling the normal constructor
    PrepInsta obj1(10);
    
    // calling user defined copy constructor (Deep Copy)
    PrepInsta obj2 = obj1; 
  
    cout << "Before value change - " << endl;
    
    // printing the values, assigned by constructors
    cout << "obj1.var = " << obj1.var << endl; 
    cout << "obj2.var = " << obj2.var << endl;
    
    obj1.var = 20;
    
    cout << "\nAfter value change - " << endl;
    
    // printing the values, assigned by constructors
    cout << "obj1.var = " << obj1.var << endl; 
    cout << "obj2.var = " << obj2.var << endl;
    
    // since we did deep copy using user defined copy constructor
    // change in obj1 is not reflected in obj2

    return  0; 
}

Output

Before value change - 
obj1.var = 10
obj2.var = 10

After value change - 
obj1.var = 20
obj2.var = 10