A copy constructor in C++ is used to create a copy of an already existed object. It is also used to Initialize one object from another of the same type.
There are two types of copy constructor:
- Default Copy constructor
- User-Defined constructor
Default Copy constructor:
The default copy constructor is defined by the compiler when the user do not define a copy constructor.
Syntax for Default Copy constructor:
1 2 3 4 | ClassName (const class_name &old_object_name) { ...... } |
let us go through the program in C++.
C++ Program of the copy constructor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | // C++ program for copy constructor #include <iostream> using namespace std; // class class Rectangle { public: float length; float breadth; Rectangle(float l, float b) // constructor { length = l; breadth = b; } Rectangle(const Rectangle &obj) // copy constructor { length = obj.length; breadth = obj.breadth; } void displayArea() { float area = length * breadth; //display cout << "Area: " << area << endl; } }; int main() { Rectangle rect1(6, 4); //parameterized constructor Rectangle rect2(rect1); //copy constructor rect2.displayArea(); //calling through the copy constructor return 0; } |
Output:
1 | Area: 24 |
Shallow Copy Constructor
A shallow copy is a process where the copy of an object is created by copying all the member’s data exactly as it is. Default copy constructor produces the shallow copy constructor.
Both the objects that are the original and copy point at the same memory. Since, both the object points to the same memory location, changes made by one will be reflected on other. Now since we only need to make a replica of the original object, shallow does not fully fill this purpose.
Let us understand through an example in C++.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | // C++ program for the shallow constructor #include <iostream> using namespace std; class Rectangle { private: int length; int *breadth; public: Rectangle() { breadth = new int; } // Function for dimension set void setDimensions(int l, int b) { length = l; *breadth = b; } //display method void display() { cout << "Length: " << length << endl; cout << "Breadth: " << *breadth << endl; } }; int main() { // Object of Rectangle Rectangle rect1; rect1.setDimensions(10, 5); //set data //copying rect1 at the time of initialization Rectangle rect2 = rect1; rect2.display(); return 0; } |
Output:
1 2 | Length: 10 Breadth: 5 |

Since the pointer breadth of both the objects (original and copied) points to the same memory location, freeing one of the memory will free the other one too. So this is solved by the Deep Constructor.
Deep Copy Constructor
A deep copy constructor is used to overcome the problem caused by the Shallow constructor. In the deep constructor, it is like having a copy of a project but both the original and copied project are kept in separate files, that is the changes made in one of the files will not affect the other.
A deep copy will allocate separate memory space for copied file. A user-defined copy constructor is used for the Deep copy constructor and assign dynamic memory as well if required.
Let us understand through an example in C++.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | // C++ program for the Deep constructor #include <iostream> using namespace std; class Rectangle { private: int length; int *breadth; public: Rectangle() { breadth = new int; } Rectangle (Rectangle &rec) { length = rec.length; breadth = new int; *breadth = *(rec.breadth); } // Function for dimension set void setDimensions(int l, int b) { length = l; *breadth = b; } //display method void display() { cout << "Length: " << length << endl; cout << "Breadth: " << *breadth << endl; } //destructor ~Rectangle() { delete breadth; } }; int main() { // Object of Rectangle Rectangle rect1; rect1.setDimensions(10, 5); //set data //copying rect1 at the time of initialization Rectangle rect2 = rect1; rect2.display(); return 0; } |
Output:
1 2 | Length: 10 Breadth: 5 |

As you can see in the program above, we use destructor to destroy the dynamically allocated memory.