Article by: Manish Methani
Last Updated: October 18, 2021 at 8:04am IST
C++ is a popular programming language used for developing a variety of software applications. It is an object-oriented programming language that allows creating new objects from existing ones. Copy Constructor is an essential concept in C++ that enables developers to create new objects from an existing object.
A Copy Constructor is a special type of constructor that creates a new object by copying an existing object. It creates an exact copy of the original object, including all its data members and member functions.
A Shallow Copy Constructor is a Copy Constructor that performs a shallow copy of the object. In a shallow copy, only the object's data members are copied, and any pointers to memory allocated dynamically are not copied. Instead, the new object points to the same memory location as the original object. This can lead to issues if the original object is modified, as the copied object will also be affected.
A Deep Copy Constructor is a Copy Constructor that performs a deep copy of the object. In a deep copy, not only the object's data members are copied, but any dynamically allocated memory is also copied to a new location. This ensures that the copied object is independent of the original object and can be modified without affecting the original object.
The syntax of a Copy Constructor is as follows:
class ClassName { ClassName(const ClassName &obj) { // Constructor code here } };
Copy Constructors are defined like regular constructors, but with a parameter of the same class type, as shown below:
class MyClass { public: MyClass(int x, int y); MyClass(const MyClass &obj); private: int x; int y; };
#include <iostream> using namespace std; class MyClass { public: int x; int y; MyClass(int xval, int yval) { x = xval; y = yval; } MyClass(const MyClass &obj) { x = obj.x; y = obj.y; } }; int main() { MyClass obj1(10, 20); MyClass obj2 = obj1; cout << obj2.x << " " << obj2.y; return 0; }
Output:
10 20
In this example, we define a class MyClass
with two data members x
and y
. We define a constructor that initializes these data members with the given values. We also define a Copy Constructor that creates a new object by copying the values of the original object's data members.
In the main()
function, we create an object obj1
of the MyClass
class and initialize it with values 10
and 20
. We then create another object obj2
and initialize it by calling the Copy Constructor with obj1
as a parameter. Finally, we print the values of `obj2`
#include <iostream> using namespace std; class MyClass { public: int *x; MyClass(int val) { x = new int(val); } MyClass(const MyClass &obj) { x = obj.x; } ~MyClass() { delete x; } }; int main() { MyClass obj1(10); MyClass obj2 = obj1; *obj2.x = 20; cout << *obj1.x << " " << *obj2.x; return 0; }
Output:
20 20
In this example, we define a class MyClass
with a single data member x
, which is a pointer to an integer. We define a constructor that initializes this pointer to a new integer value, which is passed as a parameter to the constructor. We also define a Copy Constructor that performs a shallow copy of the object.
In the main()
function, we create an object obj1
of the MyClass
class and initialize it with the value 10
. We then create another object obj2
and initialize it by calling the Copy Constructor with obj1
as a parameter. We modify the value of *obj2.x
to 20
and print the values of *obj1.x
and *obj2.x
. As we can see, both values are 20
, indicating that the shallow copy constructor did not copy the dynamically allocated memory and instead pointed obj2.x
to the same memory location as obj1.x
.
#include <iostream> using namespace std; class MyClass { public: int *x; MyClass(int val) { x = new int(val); } MyClass(const MyClass &obj) { x = new int(*obj.x); } ~MyClass() { delete x; } }; int main() { MyClass obj1(10); MyClass obj2 = obj1; *obj2.x = 20; cout << *obj1.x << " " << *obj2.x; return 0; }
Output:
10 20
In this example, we define a class MyClass
with a single data member x
, which is a pointer to an integer. We define a constructor that initializes this pointer to a new integer value, which is passed as a parameter to the constructor. We also define a Copy Constructor that performs a deep copy of the object by allocating new memory for x
and copying the value from the original object's x
.
In the main()
function, we create an object obj1
of the MyClass
class and initialize it with the value 10
. We then create another object obj2
and initialize it by calling the Copy Constructor with obj1
as a parameter. We modify the value of *obj2.x
to 20
and print the values of *obj1.x
and *obj2.x
. As we can see, the value of *obj1.x
is 10
, while the value of *obj2.x
is 20
, indicating that the deep copy constructor copied the dynamically allocated memory to a new location.
While both Copy Constructor and Assignment Operator can be used to copy objects, they have some differences. The Copy Constructor creates a new object by copying an existing object, while the Assignment Operator assigns the value of an existing object to another object. Here are some key differences between the two:
A. A Shallow Copy in C++ copies only the addresses of the dynamically allocated memory in an object, while a Deep Copy copies the values of the memory, creating a new memory block for the copy. Shallow Copy can result in objects sharing the same memory, while Deep Copy ensures each object has its own independent memory.
A. Yes, a Copy Constructor can be made private in C++ to prevent objects from being copied. This is often used in Singleton design patterns or when objects contain sensitive data that should not be copied.
A. If your class contains dynamically allocated memory or has reference data members, it is recommended to define a Copy Constructor in C++ to ensure proper copying of the data. If your class does not have any of these, the compiler will generate a default Copy Constructor for you.
A. If you do not define a Copy Constructor in C++, the compiler will generate a default one for you. This default constructor will perform a Shallow Copy of the object, which may lead to unexpected behavior if the object contains dynamically allocated memory or reference data members.
ClassName::ClassName(const ClassName& obj) { // Copy the data members of obj to the new object }
A. You can avoid using the Copy Constructor in C++ by using pointers or references to objects instead of creating copies. This can improve performance and prevent errors that may occur with copying objects.
In this tutorial, we have learned about Copy Constructor in C++, including its purpose, syntax, and examples of Shallow Copy and Deep Copy Constructors. We have also discussed the differences between Copy Constructor and Assignment Operator and answered some frequently asked questions about Copy Constructor. By understanding Copy Constructor, you can write more efficient and error-free C++ code that is easier to maintain and understand.