The copy constructor in C++ is a type of constructor that is used to create a new object as a copy of an existing object. It is important to handle resource management with dynamic memory. It is of two types: default and user-defined. In this article, we will discuss what a copy constructor in C++ is, when it is called, its types, shallow and deep copy, implicit and explicit copy constructors, the difference between copy constructors and assignment operators, why the rule of three matters, advantages, and disadvantages of copy constructors in C++.
Table of Contents:
What is a Copy Constructor in C++?
A copy constructor in C++ is a special constructor that is used to create a new object as a copy of an existing object. This constructor is called when an object is initialized from another object of the same class.
Syntax:
ClassName(const ClassName& other);
- ClassName is the name of the class.
- const is the parameter that prevents unnecessary copying in the source object.
- &other is a reference to the source object.
- other is the source object.
Example:
Output:
The code shows how the copy constructor in a C++ program creates a new object b2 as a copy of b1, and then copies and prints the title of the book as output.
When is the Copy Constructor Called in C++?
Below are a few situations where a copy constructor can be called in C++:
- When a new object is created from an existing object.
- When an object is passed by value.
- When a function returns an object by value.
- When an object is caught in a catch block by value.
- When a temporary object is created and assigned to a new object without using move semantics.
- When an STL container performs a copy internally in the function.
- When copy elision is not applied.
Types of Copy Constructor in C++
There are two types of copy constructors in C++ that are classified on the basis of the data types used.
- Default Copy Constructor
- User-Defined Copy Constructor
Let’s discuss both types in brief with examples in C++:
Default Copy Constructor in C++
The default copy constructor is a type of copy constructor that is automatically generated by the compiler if it is not defined. It performs a shallow copy, which means that it simply copies the values of each member from one object to another. Also, this shallow copying can cause double deletion and incorrect copying of resources. It can be used for simple data members such as integers, strings, etc.
Example:
Output:
The code shows that the compiler provides a default copy constructor because no copy constructor is defined, and then copies the title from b1 to b2.
User-Defined Copy Constructor in C++
A user-defined copy constructor is a type of copy constructor in which the user can write their own to copy an object. It allows more control over how an object is copied when the object contains dynamically allocated memory. By using a user-defined copy constructor, you can implement deep copying.
Example:
Output:
The code shows how a user-defined copy constructor performs a deep copy of a dynamically allocated name so that both objects, p1 and p2, manage separate memory.
Constructor Copies
There are two ways in which the constructor copies in C++.
- Shallow Copy
- Deep Copy
Shallow Copy in C++
A shallow copy is a type of copying in which the values of data members are copied from one object to another, which means that it copies to the same memory location.
Characteristics:
- It is created by the default or compiler-generated copy constructor.
- There is no new memory allocation for pointer members.
- It leads to shared ownership of the same resource.
- It can cause double deletion and undefined behavior.
Example:
Output:
The code shows how the shallow copy is done, where both b1 and b2 share the same memory for the str, which then leads to a double deletion and potential crash when the program ends.
Deep Copy in C++
A deep copy in C++ is used to create an independent copy of an object with any dynamically allocated memory, so that the object can manage its own memory safety easily.
Characteristics:
- It requires a user-defined copy constructor.
- It allocates new memory for pointer members.
- It avoids shared memory issues such as double deletion.
- It makes sure that both the original and copied objects are fully independent.
Example:
Output:
The code shows how the deep copy is used, where the copy constructor allocates new memory and copies by making sure that b1 and b2 manage memory separately.
Get 100% Hike!
Master Most in Demand Skills Now!
Shallow Copy vs Deep Copy in C++
Feature |
Shallow Copy |
Deep Copy |
Definition |
Copies only the values of data members, including pointers |
Copies values and also allocates separate memory for pointers |
Memory Sharing |
Copy the pointer addresses, both objects point to the same memory |
Allocates new memory and copies the actual data |
Constructor Used |
Compiler-generated (default copy constructor) |
User-defined copy constructor |
Performance |
Faster (less memory allocation) |
Slower (extra memory operations) |
Use Case |
Safe for simple objects without dynamic memory |
Required when an object has dynamic memory or resources |
Risk |
Risk of double deletion, dangling pointers |
Safer memory handling |
Implicit vs Explicit Copy Constructors in C++
Feature |
Implicit Copy Constructor (Compiler Generated) |
Explicit Copy Constructor (User-Defined) |
Definition |
Automatically generated by the compiler |
Written manually by the programmer |
When Provided |
When no copy constructor is explicitly defined |
When custom copy behavior is needed |
Copy Type |
Shallow copy (member-wise copy) |
Can implement shallow or deep copy |
Customization |
Not customizable |
Fully customizable |
Resource Management |
Not suitable for classes managing resources |
Suitable for classes with dynamic memory, files, etc. |
Example Use Case |
Simple structs or classes with primitive types |
Classes with pointers or complex data members |
Difference Between Copy Constructor and Assignment Operator in C++
Feature |
Copy Constructor |
Assignment Operator |
Purpose |
Initializes a new object as a copy of an existing one |
Assigns values from one existing object to another |
When can it be called |
When a new object is created from an existing object |
When an already initialized object is assigned another |
Function Signature |
ClassName(const ClassName& other) |
ClassName& operator=(const ClassName& other) |
Called On |
Uninitialized object |
Already initialized object |
Memory Handling |
Typically allocates new memory for a deep copy |
Releases old memory (if any) and copies new data |
Default Provided By |
Compiler (unless user-defined) |
Compiler (unless user-defined) |
Example |
Class a = b; |
a = b; |
Why the Rule of Three in C++ Matters for Copy Constructor?
The rule of three is very important if a class manages a resource such as dynamic memory or file handles, and then any one of the following is defined:
- Destructor
- Copy Constructor
- Copy Assignment Operator
Then all three must be defined explicitly. And if it fails to do so, then it may result in resource mismanagement such as double deletion, memory leaks, and shallow copy issues.
Thus, if a copy constructor is defined to perform a copy, and an assignment operator or destructor is not defined, then the class may not copy resources, which can lead to resource leaks.
Advantages of Copy Constructor in C++
- It helps to simplify the object duplication for simple classes.
- It supports custom copy logic or deep copy, which is ideal for handling dynamic memory resources.
- The copy constructor keeps the copy logic encapsulated in the class to avoid repetitive copying.
- It can integrate with STL containers such as vector, map, etc.
- It makes sure that the object initialization through copying is predictable and consistent.
Disadvantages of Copy Constructor in C++
- The default constructor performs shallow copies, which can lead to issues such as double deletion, dangling pointers, and shared resource conflicts.
- Deep copying can give performance overhead for large and complex objects.
- The code complexity increases due to using the copy constructor when the code has a class with dynamic memory.
- This constructor can also give recursion errors if the code is not written properly.
- If a copy constructor is defined but the assignment operator or destructor is not defined, then it may lead to resource leaks and undefined behavior.
Conclusion
The copy constructor is important in C++ to make an exact copy of any existing object, especially when dealing with dynamic memory classes. It is of two types: default and user-defined, which use different constructors for copying, such as shallow and deep copy. Also, this constructor has advantages and disadvantages that can affect C++ programming. So, by understanding what a copy constructor is, its types, uses, advantages, and disadvantages, you can easily use the copy constructor in your C++ programming.
FAQs on Copy Constructor in C++
Q1. What happens if I don't define a copy constructor?
If you don’t define a copy constructor compiler provides a default shallow copy constructor, which can cause issues for classes with dynamic memory.
Q2. Can I overload the copy constructor?
No, copy constructors cannot be overloaded; they must take a reference to the same class type.
Q3. When is the copy constructor called?
It is called when an object is initialized from another object, passed, or returned by value.
Q4. What is the difference between a copy constructor and an assignment operator?
A copy constructor creates a new object, and the assignment operator copies data into an existing object.
Q5. Why must the copy constructor take a reference?
The copy constructor must take a reference, as passing by value would lead to a recursive call, causing a compilation error.