Introduction to C++ | Copy Constructor

C++ Copy Constructor

The Copy Constructor in C++ is a special constructor that is used to create a new object as a copy of an existing object. It is typically invoked when an object is passed by value to a function or when an object is returned from a function.

What is a Copy Constructor?

A Copy Constructor is a constructor that creates an object by copying values from another object of the same class. The primary purpose of the copy constructor is to ensure that a new object is properly initialized with the values of an existing object.

The syntax for a copy constructor is as follows:

Syntax of Copy Constructor


        class ClassName {
        public:
            ClassName(const ClassName &obj) {
                // Copy values from obj to this object
            }
        };
                    

When is the Copy Constructor Called?

The copy constructor is invoked in the following cases:

Example of Copy Constructor

Here’s an example demonstrating the use of a copy constructor in C++:

Code Example: Copy Constructor


        #include <iostream>
        using namespace std;
        
        class Car {
        public:
            string brand;
            int year;
        
            // Parameterized constructor
            Car(string b, int y) {
                brand = b;
                year = y;
            }
        
            // Copy constructor
            Car(const Car &other) {
                brand = other.brand;
                year = other.year;
            }
        
            // Member function to display car details
            void displayDetails() {
                cout << "Brand: " << brand << ", Year: " << year << endl;
            }
        };
        
        int main() {
            // Creating an object of class Car using parameterized constructor
            Car myCar1("Honda", 2022);
            myCar1.displayDetails();  // Output: Brand: Honda, Year: 2022
        
            // Creating a copy of myCar1 using the copy constructor
            Car myCar2 = myCar1;  // Copy constructor is called
        
            myCar2.displayDetails();  // Output: Brand: Honda, Year: 2022
        
            return 0;
        }
                    

Output:

Brand: Honda, Year: 2022
Brand: Honda, Year: 2022

Deep Copy vs Shallow Copy

By default, the copy constructor performs a shallow copy. A shallow copy means that the new object will share the same memory as the original object, which may lead to problems if the objects hold pointers to dynamically allocated memory.

If your class contains pointers or dynamically allocated memory, you may need to write a custom copy constructor to perform a deep copy, where the new object gets a separate copy of the dynamically allocated memory.

Example of Deep Copy in Copy Constructor

Here’s an example of a custom copy constructor implementing a deep copy:

Code Example: Deep Copy Constructor


        #include <iostream>
        using namespace std;
        
        class Car {
        public:
            string* brand;
            int year;
        
            // Constructor with dynamic memory allocation
            Car(string b, int y) {
                brand = new string(b);
                year = y;
            }
        
            // Deep copy constructor
            Car(const Car &other) {
                brand = new string(*other.brand);  // Allocate new memory for brand
                year = other.year;
            }
        
            // Destructor to free dynamically allocated memory
            ~Car() {
                delete brand;  // Free the allocated memory
            }
        
            // Member function to display car details
            void displayDetails() {
                cout << "Brand: " << *brand << ", Year: " << year << endl;
            }
        };
        
        int main() {
            // Creating an object of class Car using parameterized constructor
            Car myCar1("Honda", 2022);
            myCar1.displayDetails();  // Output: Brand: Honda, Year: 2022
        
            // Creating a copy of myCar1 using the copy constructor
            Car myCar2 = myCar1;  // Deep copy constructor is called
        
            myCar2.displayDetails();  // Output: Brand: Honda, Year: 2022
        
            return 0;
        }
                    

Output:

Brand: Honda, Year: 2022
Brand: Honda, Year: 2022

Pro Tip:

💡 Pro Tip

The copy constructor is important when dealing with classes that involve dynamic memory management. Always remember to implement a deep copy when dealing with pointers or dynamic memory in order to avoid memory corruption and prevent issues with multiple objects pointing to the same memory location.